Django學習筆記--Forms組件

Forms組件的使用

在html表單驗證中,需要通過各種信息的驗證,比如注冊界面的姓名、密碼、郵箱、電話等的驗證,是否符合定義好的規(guī)則,不可能每次都要取出對應的字段一一判斷,django內(nèi)置了Forms組件,可以方便的在HTML中進行校驗等信息設置

1.Forms組件的作用

1.數(shù)據(jù)校驗

2.渲染頁面

3.渲染錯誤信息

4.使用局部或者全局的鉤子函數(shù)

5.設置CSS樣式

2.Forms組件的使用

  • 1.導入froms模塊 from django import forms
  • 2.定義一個類繼承自forms.Form,編寫校驗的字段,該字段就是html頁面上提交數(shù)據(jù)上傳的字段
class RegisterForms(Form):

    # 添加的字段類型中的屬性,每個子類都繼承自field,
    #field中對應的屬性和釋義
    #required=True,               是否是必須驗證,默認為True
    #widget=None,                 HTML插件,添加類名,設置placeholder等等
    #label=None,                  用于生成Label標簽或顯示內(nèi)容
    #initial=None,                初始值
    #help_text='',                幫助信息(在標簽旁邊顯示)
    #error_messages=None,         錯誤信息 {'required': '不能為空', 'invalid': '格式錯誤'}
    #validators=[],               自定義驗證規(guī)則
    #localize=False,              是否支持本地化
    #disabled=False,              是否可以編輯
    #label_suffix=None            Label內(nèi)容后綴
    
    name = forms.CharField(min_length=3,max_length=8,
                           label="用戶名",
                           error_messages={'min_length':'用戶名最少為3位',
                                           'max_length':'用戶名最多8位',
                                           'required':'名稱不能為空'})

    pwd = forms.CharField(min_length=6, max_length=20,
                          label='請輸入密碼',
                          error_messages={'min_length':'密碼最少為6位',
                                          'max_length':'密碼最多20位',
                                          'required':'密碼不能為空'})

    re_pwd = forms.CharField(min_length=6, max_length=20,
                             label='請確認密碼',
                             error_messages={'min_length':'密碼最少為6位',
                                             'max_length':'密碼最多20位',
                                             'required':'密碼不能為空'})

    phone = forms.CharField(label="請輸入手機號碼",
                            error_messages={'placerholder': '請輸入手機號碼'})

    email = forms.EmailField(label='請輸入郵箱',required=False,
                             error_messages={'invalid':'郵箱格式不合法',
                                             'max_length':'密碼最多20位'}) 
# 對于多傳的字段不會出錯,cleaned_data中不包含多傳的字段
# 少傳的字段會報錯,相當于對應的字段沒有值
                                                 
  • 3.在對應的views視圖中進行校驗,
def form_index(request):
    post_forms = RegisterForms()
    error = ''
    if request.method == 'POST':
        post_forms = RegisterForms(request.POST)
        # 4 調(diào)用forms的is_valid方法,完成校驗,is_valid返回true或者false
        if post_forms():
            register = post_forms.cleaned_data
            print(register)
            return HttpResponse('注冊成功')
        else:
            from django.forms.utils import ErrorDict
            # 獲取全局的error信息,只顯示第一個
            if post_forms.errors.get('__all__'):
                error = post_forms.errors.get('__all__')[0]

    return render(request, 'FormsTest/forms_index.html',locals())
  • 4.通過模板渲染,渲染模板有如下幾種方式,具體使用如下
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>forms登錄</title>
    {% load static %}
    <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
    <script src="{% static 'jquery-3.3.1.js' %}"></script>
    <style>
        .edit-author{
            margin: 100px 300px;
        }
        .errorinfo{
            color: red;
            font-size: 15px;
            padding-left: 15px;
        }

    </style>
</head>
<body>

<div class="edit-author">
{#    <form action="" method="post">#}
{#        {% csrf_token %}#}
{#        <div class="form-group">#}
{#            <label for="exampleInputEmail1">用戶名</label>#}
{#            <input type="text" name="name" class="form-control" placeholder="請輸入用戶名" >#}
{#        </div>#}
{#        <div class="form-group">#}
{#            <label for="exampleInputPassword1">密碼</label>#}
{#            <input type="password" name="pwd" class="form-control" placeholder="請輸入密碼">#}
{#        </div>#}
{#        <div class="form-group">#}
{#            <label for="exampleInputPassword1">確認密碼</label>#}
{#            <input type="password" name="re_pwd" class="form-control" placeholder="請確認密碼">#}
{#        </div>#}
{#        <div class="form-group">#}
{#            <label for="exampleInputPassword1">郵箱</label>#}
{#            <input type="email" name="email" class="form-control" placeholder="請輸入郵箱">#}
{#        </div>#}
{##}
{#        <button type="submit" id="clickBtn" class="btn btn-default submit-button">注冊</button>#}
{#        <span id="error"></span>#}
{#    </form>#}


{#    forms渲染頁面第一種方式#}
{#    <form action="" method="post">#}
{#        {% csrf_token %}#}
{#        <div class="form-group">#}
{#            <label for="exampleInputEmail1">用戶名</label>#}
{#            {{ post_forms.name }}#}
{#        </div>#}
{#        <div class="form-group">#}
{#            <label for="exampleInputPassword1">密碼</label>#}
{#            {{ post_forms.pwd }}#}
{#        </div>#}
{#        <div class="form-group">#}
{#            <label for="exampleInputPassword1">確認密碼</label>#}
{#            {{ post_forms.re_pwd }}#}
{#        </div>#}
{#        <div class="form-group">#}
{#            <label for="exampleInputPassword1">郵箱</label>#}
{#            {{ post_forms.email }}#}
{#        </div>#}
{#        <button type="submit" id="clickBtn" class="btn btn-default submit-button">注冊</button>#}
{#    </form>#}

    {#    forms渲染頁面第二種方式,推薦使用#}
    <form action="" method="post" novalidate>
        {% csrf_token %}
        {% for foo in reg_forms %}
            <div class="form-group">
                {# errors是一個列表,一般取第一個就可以了,這樣不會換行處理#}
                <label for="exampleInputEmail1">{{ foo.label }}</label>
                <span class="errorinfo"> {{ foo.errors.0 }}</span>
                {{ foo }}
            </div>
        {% endfor %}
        <button type="submit" id="clickBtn" class="btn btn-default submit-button">注冊</button>
        <span class="errorinfo">{{ error }} </span>
    </form>

{#    forms渲染頁面第二種方式,不推薦使用#}
{#    <form action="" method="post">#}
{#        {% csrf_token %}#}
{#        {{ post_forms.as_p }}#}
{#        {{ post_forms.as_ul }}#}
{#        {{ post_forms.as_table }}#}
{#        <button type="submit" id="clickBtn" class="btn btn-default submit-button">注冊</button>#}
{#    </form>#}

</div>

</body>
</html>
最后效果圖
  • 5.上面只是實現(xiàn)了部分的校驗,而且展示的樣式需要手動渲染,我們可以在定義模型的時候直接設置好對應的css展示樣式和自定義校驗規(guī)則,比如電話號碼的正則校驗等等
#導入widgets模塊,設置css的展示樣式
from django.forms import widgets

#接下來修改對應的name,pwd,phone等字段,添加新屬性,如下添加了占位符和類名這個時候的登錄界面就和上面的一樣

name = forms.CharField(min_length=3,max_length=8,
                           label="用戶名",
                           widget=widgets.TextInput(attrs={'class': 'form-control',
                                                            'placeholder': '請輸入名稱(3-8字符)'}),
                           error_messages={'min_length':'用戶名最少為3位',
                                           'max_length':'用戶名最多8位',
                                           'required':'名稱不能為空'})

    pwd = forms.CharField(min_length=6, max_length=20,
                          label='請輸入密碼',
                          widget=widgets.PasswordInput(attrs={'class':'form-control',
                                                              'placeholder':'請輸入密碼(6-20字符)'}),
                          error_messages={'min_length':'密碼最少為6位',
                                          'max_length':'密碼最多20位',
                                          'required':'密碼不能為空'})

    re_pwd = forms.CharField(min_length=6, max_length=20,
                             label='請確認密碼',
                             widget=widgets.PasswordInput(attrs={'class': 'form-control',
                                                                 'placeholder': '請確認密碼'}),
                             error_messages={'min_length':'密碼最少為6位',
                                             'max_length':'密碼最多20位',
                                             'required':'密碼不能為空'})

    phone = forms.CharField(label="請輸入手機號碼",
                            widget=widgets.TextInput(attrs={'class': 'form-control',
                                                            'placeholder': '請輸入手機號碼'}),
                            error_messages={'placerholder': '請輸入手機號碼'})

    email = forms.EmailField(label='請輸入郵箱',required=False,
                             widget=widgets.TextInput(attrs={'class': 'form-control',
                                                             'placeholder': '請輸入郵箱'}),
                             error_messages={'invalid':'郵箱格式不合法',
                                             'max_length':'密碼最多20位'})

  • 6.自定義校驗規(guī)則,有時django自帶的校驗并不能滿足我們所有的需求,比如校驗密碼輸入,不能用特殊字符,手機號碼格式定義正則等,這就需要我們自定義規(guī)則
#自定義校驗規(guī)則
def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    if not mobile_re.match(value):
        raise ValidationError('手機號碼格式錯誤')
        
#在定義字段的時候添加校驗規(guī)則,校驗規(guī)則傳入的是一個列表,可以有多個校驗規(guī)則
phone = forms.CharField(label="請輸入手機號碼",
                            validators=[mobile_validate,],
                            widget=widgets.TextInput(attrs={'class': 'form-control',
                                                            'placeholder': '請輸入手機號碼'}),
                            error_messages={'placerholder': '請輸入手機號碼'})

  • 7.自定義鉤子,實現(xiàn)自定義的錯誤提示和校驗規(guī)則,
#Django中鉤子分為局部鉤子和全局鉤子,
# 局部鉤子函數(shù)(某個字段,自定義的規(guī)則,數(shù)據(jù)庫是否存在,以什么開頭)
# 方法名必須為:clean_字段名
def clean_name(self):
    #獲取到當前對象,是cleaned_data之后的數(shù)據(jù)
    name = self.cleaned_data.get('name')
    if name.startswith('sb'):
        #以sb開頭了返回錯誤信息,禁止使用sb開頭的用戶名
        raise ValidationError('不能以sb開頭')
    # 數(shù)據(jù)庫中查詢有沒有這個名稱
    user = models.UserInfo.objects.filter(username=name).first()
    if user:
        raise ValidationError('用戶名已存在')
    return name
    
#全局鉤子,方法名必須是clean
#校驗兩次密碼是否相同等,
def clean(self):
    pwd = self.cleaned_data.get('pwd')
    re_pwd = self.cleaned_data.get('re_pwd')
    if pwd == re_pwd:
        return self.cleaned_data
    else:
        raise ValidationError('兩次密碼不一致')

3.最后實現(xiàn)的效果如下圖

最后的效果
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容