Django フォーム コンポーネント - HTML を直接レンダリングする魔法のバックエンド

序文

フォーム form を使用して HTML ページのバックエンドにデータを送信する前に、ユーザー入力を取得するいくつかのタグが記述され、form タグでラップされます。また、多くのシナリオでは、ユーザーの入力の長さや形式など、ユーザーの入力を検証する必要があります. ユーザーの入力が間違っている場合は、対応するエラーメッセージをページ上の対応する位置に表示する必要があります. django フォーム コンポーネントは、上記の機能を実装しています。

フォームコンポーネント機能

要約すると、django from コンポーネントの主な機能は次のとおりです。

① ページで使用できる HTML タグを生成します。

② ユーザーが提出したデータを検証します。

③前回入力した内容を保持します。

フォームコンポーネントの基本的な使い方

フォーム コンポーネントの使用法は django モデルと非常に似ています.クラスはapplicationviews.pyで定義され、コードは次のようになります:form

# views.py
from django import forms
class MyForm(forms.Form):
    '''
    # username字符串类型最小3位最大8位
	# password字符串类型最小3位最大8位
	# email字段必须符合邮箱格式  [email protected]
	# label属性用来指定字段展示信息
    '''
    # username字符串类型,最小3位,最大8位
    username = forms.CharField(max_length=8,min_length=3, lable='用户名')
    # password,字符串类型,最小3位,最大8位
    password = forms.CharField(max_length=8,min_length=3, lable='密码')
    # email字段必须符合邮箱格式
    email = forms.EmailField(lable='邮箱')

フォームコンポーネントの環境をテストする方法も 2 通りあります. 1 つは を渡す方法でtest.py, もう 1 つは pycharm のテスト環境を渡す方法ですPython console. ここでは 2 番目の方法を使用してテストします.

# 1 导入需要测试的文件
from first import views

# 2 将需要校验的数据组织成字典的形式传入自定义的form类进行校验
form_obj = views.MyForm({'username':'python',,'emali':'123'})

# 3 判断数据是否合法:注意该方法只有在所有的数据全部合法的情况下才会返回True
form_obj.is_valid()  # False

# 4 查看所有通过校验的数据
form_obj.cleaned_data  # {'username': 'python', }

# 5 查看所有不符合校验规则的字段和不符合原因,错误原因是列表,因为可能错误原因有多个
form_obj.errors  # {'email': ['Enter a valid email address.']}

# 6 如果校验数据中出现了类中没有的字段,forms组件只会校验存在的字段,不存在的字段传了直接忽略
form_obj = views.MyForm({'username':'python',,'emali':'[email protected]','hobby':'read'})
form_obj.is_valid()  # True

# 7 默认情况下,类里面所有的字段都必须传值,也就意味着校验数据的时候,默认情况下数据可以多传但是不能少传
form_obj = views.MyForm({'username':'jason',})
form_obj.is_valid()  # False

フォーム コンポーネントの検証ルールは、次のように要約できます。

给MyForm传值实例化对象,传值方式:将带校验的字段和数据组织成字典的形式
is_valid()		该方法只有在所有的数据全部合法的情况下才会返回True
cleaned_data	查看所有校验通过的数据
errors			查看所有不符合校验规则以及不符合的原因,{key: ['']}
has_error()		判断某一个字段是否不合法,不合法返回True

校验数据只校验类中出现的字段,多传不影响,多传的字段直接忽略
校验数据 默认情况下 类里面所有的字段都必须传值,即少传肯定不合法

フォーム コンポーネントはタグをレンダリングします

上記のように、フォーム コンポーネントはユーザー入力のラベル (入力選択ラジオ チェックボックス) を自動的にレンダリングできますが、送信ボタンを自動的にレンダリングすることはできません。views.py1 つ目は、 view 関数が記述されているバックエンドのコードです。

# views.py
def index(request):
    # 先产生一个空对象
    form_obj = MyForm()
    
    if request.method == 'POST':
        # 获取用户数据进行校验,如果一条一条的获取用户数据太过繁琐,而且校验数据需要字典格式,而request.POST获取到的数据格式就是queryset——dict对象
        form_obj = MyForm(request.POST)
        # 如果数据合法应该操作数据库,这里先简写
        if form_obj.is_valid():
            return HttpResponse('OK')
        
    # 如果是get请求返回直接将空对象传递给html页面
    return render(request,'register.html',locals())

データが不正で、エラー情報をフロントエンドに表示する必要がある場合、エラー情報をフロントエンドに表示するにはどうすればよいですか? フォーム検証によって生成されるエラー情報は辞書形式であり、フロント エンドはカスタム オブジェクトであるため、フロント エンドを使用してポイント アンド クリックすることができますregister.html页面

<body>
<form action="" method="post" novalidate>  <!--novalidate参数阻止浏览器自动校验-->
    {% for form in form_obj %}
        <p>
            {
   
   { form.label }} : {
   
   { form }}
        <!--span是预留的展示错误信息的标签,form.errors.0的意思是只展示第一条错误提示,否则forms组件会将错误信息展示成无序列表的形式-->
        <span style="color: red">{
   
   { form.errors.0 }}</span>
        </p>

    {% endfor %}
    <input type="submit">
</form>
</form>
</body>

フロントエンドに表示されるエラーメッセージはすべて英語ですが、中国語に変更できますか? パラメータを使用してエラー メッセージをカスタマイズできますerror_messages

class MyForm(forms.Form):
    '''
    error_messages参数需要构造成字典的数据结构,key是校验条件,value是校验失败时的提示信息
    '''
    username = forms.CharField(min_length=5,
                               max_length=12,
                               label='用户名',
                               error_messages={
                                   'min_length': '用户名不能少于5位',
                                   'max_length': '用户名不能超多12位',
                                   'required': '用户名不能为空',
                               }
                               )
    password = forms.CharField(min_length=6, max_length=12, label='密码')
    re_password = forms.CharField(min_length=6, max_length=12, label='确认密码')
    email = forms.EmailField(label='邮箱')

HOOK フック機能

上記のフォームコンポーネントの基本的な使い方は、データ検証の最初の層だけです. 多くの場合、パラメータにはいくつかの特別な検証規則が必要です. このとき、フック関数を使用できます. フック関数は2番目の層と同様です.フォーム コンポーネントの検証. , これにより、検証ルールをカスタマイズできます. 検証プロセスが検証の最初の層を通過した後, フック関数に到達します. フック関数で検証ルールをさらにカスタマイズできます. フック関数フックは、ローカルフックとグローバルフックの2種類に分けられますフック、フック機能はformクラスで定義されています。

部分フック

検証ルールを 1 つのフィールドに追加する必要がある場合は、部分フックを使用できます。たとえば、ユーザー名を含めることはできないと規定されていますhook

# views.py
class MyForm(forms.Form):
    username = forms.CharField(min_length=5,
                               max_length=12,
                               label='用户名',
                               error_messages={
                                   'min_length':'用户名不能少于5位',
                                   'max_length':'用户名不能超多12位',
                                   'required':'用户名不能为空',
                               })

    def clean_username(self):
        username = self.cleaned_data.get('username')
        if '666' in username:
            self.add_error('username', '中包含了hook')
        return username

ローカル フック関数の定義は、次のように要約できます。

①ローカルフックの関数名は: でclean_字段()、フィールドはカスタム検証ルールのフィールドです。

②このメソッドでは、cleaned_dataこのフィールドのデータは で取得され、現在のフィールドのデータのみが部分フックで取得されます。

③ 検証データが失敗した場合、add_errorメソッドを介してフィールドにエラー情報を追加します。

④ローカルフックで取得したフィールドデータを返す必要があります。

グローバルフック

検証ルールを複数のフィールドに追加する必要がある場合は、グローバル フックを使用できます。たとえば、2 つのパスワード入力が一致しているかどうかを確認するには、次のようにします。

# views.py
class MyForm(forms.Form):
    
    password = forms.CharField(min_length=6, max_length=12, label='密码')
    re_password = forms.CharField(min_length=6, max_length=12, label='确认密码')
   
    def clean(self):
        password = self.cleaned_data.get('password')
        re_password = self.cleaned_data.get('re_password')
        if password != re_password:
            self.add_error('re_password', '两次密码输入不一致')

        return self.cleaned_data

グローバル フック関数の定義は、次の点に要約できます。

①グローバルフックは任意のフィールドのデータを取得cleaned_dataできます。

②グローバルフックで取り出したものはcleaned_data返却しなければなりません。

フォーム コンポーネント パラメータの紹介

1 つ目は、共通のパラメーターです。

min_length			最少几位字符
max_length			最多几位字符
label				字段名
required  			控制字段是否必填(默认required=True)
error_messages  	自定义报错信息,字典的结构
initial  			初始值,input框里面的初始值value

HTML ページのタグは属性を変更できるため、フォーム コンポーネントは直接レンダリングされます。タグの属性を変更するにはどうすればよいですか? これはwidget、ラベルのプロパティを変更できるパラメーターを介して行われます。

class MyForm(forms.Form):
    username = forms.CharField(min_length=5,
                               max_length=12,
                               widget=forms.widgets.TextInput(attrs={'class': 'form-control'}))

"""
总结:
widget=forms.widgets.TextInput()默认是TextInput(及input[type='text'])
widget=forms.widgets.PasswordInput()密码格式
widget=forms.widgets.EmailInput()邮箱格式

attrs提供字段的属性,可以是内置的也可以是自定义的;如有多个class:空格隔开即可。
"""

さらに、最初の検証ルールでは、通常の検証もサポートされています。つまり、validators通常の検証はパラメーターを介して実行されます。

from django import forms
from django.core.validators import RegexValidator

class MyForm(forms.Form):
 
    phone = forms.CharField(label='手机号',
                            validators=[
                                RegexValidator(r'^[0-9]+$', '请输入数字'),
                                RegexValidator(r'^159[0-9]+$', '数字必须以159开头')
                            ],)
   
"""
总结:
validators的值是一个列表,烈面可以更多个正则表校验条件
RegexValidator第一个参数是正则表校验条件,第二个是校验失败是的提示信息

"""

フォーム コンポーネントのその他のラベルのレンダリング

フォーム コンポーネントは、inputフレームをレンダリングするだけでなく、radio select checkboxラベルのレンダリングもサポートします。

# radio单选
gender = forms.ChoiceField(
    choices=((1, "男"), (2, "女"), (3, "保密")),
    label="性别",
    initial=1,
    widget=forms.widgets.RadioSelect()
)

# checkbox多选
hobby = forms.MultipleChoiceField(
    choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
    label="爱好",
    initial=[1, 3],
    widget=forms.widgets.CheckboxSelectMultiple()
)


# 下拉单选:即使添加attrs={'multiple': 'multiple'}任然为单选
hobby2 = forms.ChoiceField(
    choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
    label="爱好",
    initial=3,
    widget=forms.widgets.Select()
)

# 下拉多选
hobby3 = forms.MultipleChoiceField(
    choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
    label="爱好2",
    initial=[1, 3],
    widget=forms.widgets.SelectMultiple()
)

# 选择checkbox是否选择, initial空表示False, 只要有值就是True默认选中(任何值都可以)
keep = forms.ChoiceField(
    choices=(('False', 0), ('True', 1)),
    label="是否记住密码",
    initial='',
    widget=forms.widgets.CheckboxInput()
)

パラメータを使用して表示データをデータベースから動的に取得するchoice場合は、追加の設定が必要です。choices

class BookAddForm(forms.Form):
    name = forms.CharField(label='图书名称',
                           error_messages={'required': '图书名称不能为空'},
                           widget=forms.widgets.TextInput())
    
    price = forms.DecimalField(label='价格',
                               error_messages={'required': '图书价格不能为空'},
                               widget=forms.widgets.TextInput())
    
    publish_date = forms.DateField(label='出版日期',
                                   error_messages={'required': '出版日期不能为空'},
                                   widget=forms.widgets.DateInput())
    
    publish_id = forms.ChoiceField(label='出版社',
                                   error_messages={'required':'出版社不能为空'},
                                   widget=forms.widgets.Select())
    
    author = forms.MultipleChoiceField(label='作者',
                                       error_messages={'required':'作者不能为空'},
                                       widget=forms.widgets.SelectMultiple())

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # choices字段的数据动态来自数据库
        self.fields['publish_id'].choices = models.Publish.objects.values_list('pk', 'name')
        self.fields['author'].choices = models.Author.objects.values_list('pk', 'name')

おすすめ

転載: blog.csdn.net/nhb687095/article/details/130465656