forms組件

forms組件

當咱們好比在註冊頁面的時候,獲取用戶輸入的用戶名、密碼或郵箱是否符合咱們設置的規則,好比設置密碼長度,當不足的時候會提示信息html

後端代碼:前端

def register(request):
    # 定義錯誤信息空字典
    error_dict = {'username': '', 'password': ''}
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if '666' in username:
            error_dict['username'] = '光喊666是不行的!!!'
        if not password:
            error_dict['password'] = '密碼不能爲空!!!'
    return render(request, 'register.html', locals())

前端代碼:django

<form action="" method="post">
    <p>用戶名: 
        <input type="text" name="username"> 
        <span style="color: red">{{ error_dict.username }}</span>
    </p>
    <p>密碼: 
        <input type="text" name="password"> 
        <span style="color: red">{{ error_dict.password }}</span>
    </p>
    <input type="submit">
</form>

以上咱們作了:後端

一、手寫獲取用戶輸入的前端頁面代碼    >>> 渲染頁面瀏覽器

二、後端獲取用戶數據並作合法校驗       >>> 校驗數據ide

三、將校驗以後的結果渲染到前端頁面    >>> 展現信息函數

咱們能夠經過forms組件來幫咱們作這些事post

總結一下,其實form組件的主要功能以下:測試

  • 生成頁面可用的HTML標籤
  • 對用戶提交的數據進行校驗
  • 保留上次輸入內容

一、先寫一個類

from django import forms
class MyForms(forms.Form):
    # 用戶名最大8位,最少2位,錯誤提示信息,容許爲空,默認值
    username = forms.CharField(max_length=8, min_length=2,
                               error_messages={
                                   'max_length': '用戶名最長8位',
                                   'min_length': '用戶名最短2位',
                               }, required=False, initial='shen')
    # 密碼必須最少3位最多8位,且標籤名是密碼,控制type屬性爲password
    password = forms.CharField(max_length=8, min_length=3, label='密碼:',
                               widget=forms.widgets.PasswordInput(attrs={'class':'form-control'}))
    # 必須郵箱格式
    email = forms.EmailField(error_messages={
        'required': '郵箱必填',
        'invalid': '郵箱格式不正確'
    })
    # 引用模塊validators中RexValidator進行正則校驗
    phone = forms.CharField(
        validators=[
            RegexValidator(r'^[0-9]+$', '請輸入數字') ]
    )

經常使用的參數:

 label               input的提示信息
        error_messages      自定義報錯的提示信息
        required            設置字段是否容許爲空,容許爲空改成False
        initial             設置默認值
        widget              控制type類型及屬性
            widget=forms.widgets.TextInput(attrs={'class':'form-control c1  c2'})
            widget=forms.widgets.PasswordInput(attrs={'class':'form-control'})
        validators          正則校驗
             validators=[
            RegexValidator(r'^[0-9]+$', '請輸入數字')
        ]

其餘字段及參數 

# 單選
    gender = forms.ChoiceField(
        choices=((1, ""), (2, ""), (3, "保密")),
        label="性別",
        initial=3,
        widget=forms.widgets.RadioSelect()
    )
    # 單選下拉框
    hobby = forms.ChoiceField(
        choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),),
        label="愛好",
        initial=3,
        widget=forms.widgets.Select()
    )
    # 多選
    hobby1 = forms.MultipleChoiceField(
        choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),),
        label="愛好",
        initial=[1, 3],
        widget=forms.widgets.SelectMultiple()
    )
    # 單選
    keep = forms.ChoiceField(
        label="是否記住密碼",
        initial="checked",
        widget=forms.widgets.CheckboxInput()
    )
    # 多選
    hobby2 = forms.MultipleChoiceField(
        choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),),
        label="愛好",
        initial=[1, 3],
        widget=forms.widgets.CheckboxSelectMultiple()
    )
其餘字段及參數

二、後端校驗數據

def reg(request):
    # 先生成一個空的類的對象
    form_obj = MyForms()
    if request.method == 'POST':
        # 獲取用戶數據並交給forms組件校驗  request.POST
        # 此處form_obj與上面定義的空對象要相同
        form_obj = MyForms(request.POST)
        # 獲取校驗結果
        if form_obj.is_valid():
            return HttpResponse('數據沒問題')
        else:
            # 獲取校驗失敗的字段和提示信息
            print(form_obj.errors)
    # 直接將該對象傳給前端頁面
    return render(request, 'reg.html', locals())

校驗數據的方法:

一、將數據字典傳入咱們寫的類中ui

form_obj = MyForms({'username':'shen', 'password': '11', 'email': '111', 'phone': '1234'})

二、判斷數據是否符合校驗規則

form_obj.is_valid() # 該方法獲得結果只有True和False,只有所有經過校驗纔會返回True

三、獲取哪些數據是校驗經過的

form_obj.cleaned_data

四、獲取哪些數據是校驗失敗的,和失敗緣由

form_obj.errors

五、注意:forms組件全部的字段都必需要傳參,不能少了,可是傳多了沒事,多傳的會自動忽略

form_obj = views.MyRegForm({'username':'jason','password':'123456','phone':'11213'})
            form_obj.is_valid()
            # False
            form_obj.errors
            # {'email': ['This field is required.']}
​
form_obj=views.MyRegForm({'username':'jason','password':'123456',"email":'123@qq.com',"hobby":'hahahaha'})
            form_obj.is_valid()
            # True
            form_obj.cleaned_data
            # {'username': 'jason', 'password': '123456', 'email': '123@qq.com'}
            form_obj.errors
            # {}

三、在前端渲染頁面

校驗數據先後端都應該要有的,可是前端的校驗弱不由風容易被修改,因此後端的校驗必需要很是全面

如何取消前端瀏覽器幫咱們作的自動校驗功能:利用form表單中的 novalidate

<form action="" method="post" novalidate>

form組件會幫你在前端渲染用戶的輸入(選擇,輸入,下拉,文件)的標籤,不會渲染按鈕,而且渲染出的默認提示信息都是類中的字段首字母大寫

三種渲染方式:

{#第一種渲染方式  本地測試方便,封裝程度很高,擴展性低#}
<form action="" method="post">
    {{ form_obj.as_p }}   每個input框都是p標籤
    {{ form_obj.as_table }}   按照表格渲染一行展現
    {{ form_obj.as_ul }}   按照無序列表渲染展現
    <input type="submit">
</form>
{#第二種渲染方式  擴展性高,可是書寫太繁瑣#}
<form action="" method="post">
{#    給username添加label標籤和id#}
    <label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label>
{{ form_obj.username }}
{#    獲取標籤的展現信息           獲取標籤input框#}
{{ form_obj.password.label }} {{ form_obj.password }}
{{ form_obj.email.label }}: {{ form_obj.email }}
{{ form_obj.phone.label }}: {{ form_obj.phone }}
    <input type="submit">
</form>
{#第三種渲染方式  推薦使用#}
<form action="" method="post" novalidate>
{#    循環取出沒一個字段#}
    {% for form in form_obj %}         <p>
{#        字段展現提示信息    字段input框#}
        {{ form.label }} {{ form }}
{#            渲染錯誤提示信息#}
    <span>{{ form.errors.0 }}</span>
        </p>
    {% endfor %}
    <input type="submit">
</form>

四、鉤子函數

實現自定義的校驗功能,在自定義類下使用鉤子函數

一、全局鉤子

在form類中使用 clean() 方法,實現同時對多個字段進行操做

    # 定義全局鉤子來校驗兩次密碼是否相同
    # 定義全局鉤子,必須是clean
    def clean(self):
        # 獲取字段對應的數據
        password = self.cleaned_data.get('password')
        repassword = self.cleaned_data.get('repassword')
        if not password == repassword:
            # 添加錯誤提示到repassword字段中的錯誤信息中
            self.add_error('repassword', '兩次密碼不同!!!')
        # 返回拿到的全局數據
        return self.cleaned_data

二、局部鉤子

在form類中使用 clean_字段名() 方法,實現對某一個字段的校驗

    # 定義局部鉤子校驗用戶名中不能有GG
    def clean_username(self):
        # 獲取局部定義鉤子操做的字段數據
        username = self.cleaned_data.get('username')
        if 'GG' in username:
            # 添加錯誤信息到username錯誤信息中
            self.add_error('username', 'GG是不行的')
        # 返回拿到的局部鉤子字段
        return username

 

總結:若是想同時操做多個字段的數據就用全局鉤子,若是想操做單個字段的數據,就用局部鉤子

相關文章
相關標籤/搜索