form組件

form組件

這裏拋出一個問題css

校驗:html

1.註冊功能
用戶輸入的用戶名中 不能包含‘xxx’
若是包含了 就提示用戶 輸入的內容不符合社會主義核心價值觀
用戶輸入的密碼 不能小於三位
若是密碼少於三位 提示用戶 密碼過短了
校驗數據一般是先後端都有校驗
可是前端校驗無關緊要 哪怕再牛逼
後端也必需要有校驗 反正一句話 前端可有不校驗 後端必須校驗!!前端

(深深的體現了開發鄙視鏈)jquery

這個時候用form組件就能夠自動幫咱們完成三個功能:django

1.搭建前端頁面(渲染頁面)
2.獲取前端用戶提交的數據校驗(校驗數據)
3.對數據的校驗的結果 展現到前端頁面給用戶查看 (展現錯誤信息)bootstrap

咱們首先須要本身寫一個繼承了Form的類。後端

from django import forms
class MyRegForm(forms.Form):
   username = forms.CharField(min_length=3,max_length=8)
   password = forms.CharField(min_length=3,max_length=8)
   email = forms.EmailField()

如何校驗數據?瀏覽器

from app01 import views
            # 1.給自定義的類傳一個字典
            obj = views.MyRegForm({'username':'jason','password':'12','email':'123'})
            # 2.判斷數據是否所有合法
            obj.is_valid()  # 只有數據所有符合要求才會是True
            Out[4]: False
            # 3.查看符合校驗規則的數據
            obj.cleaned_data
            Out[5]: {'username': 'jason'}
            # 4.查看不符合條件的數據以及不符合的緣由是什麼
            obj.errors
            Out[6]: 
            {
                'password': ['Ensure this value has at least 3 characters (it has 2).'],
                'email': ['Enter a valid email address.']
             }
            
            # 5.校驗數據的時候 默認狀況下類裏面全部的字段都必須傳值
            obj = views.MyRegForm({'username':'jason','password':'123'})
            obj.is_valid()
            Out[12]: False
            obj.errors
            Out[13]: {'email': ['This field is required.']}
            # 6.默認狀況下能夠多傳 可是絕對不能少傳
            obj = views.MyRegForm({'username':'jason','password':'1233','email':'123@qq.com','xxx':'ooo'})
            obj.is_valid()
            Out[15]: True

這裏要介紹一下在pycharm裏的一個功能,下面的Python Console,他會自動幫咱們搭配好django環境,在這裏對咱們的輸入返回結果,上面代碼中的 Out就是返回結果。app

上述代碼中,咱們給本身寫的form類裏面傳了一個字典,能看到的是隻有 username 是符合要求的,其中各類 form 自帶的方法都已經作出瞭解釋,就不一一贅述了。函數

如何渲染頁面

既然咱們已經得到告終果,那麼要怎麼樣才能在前端頁面上展現出來呢?

首先要注意一點 :forms組件只會幫你渲染獲取用戶輸入(輸入,選擇,下拉框...)的標籤 提交按鈕須要你本身手動寫

三種渲染前端頁面的方式

第一種:

{{ form_obj.as_p }} //as_p 是會把你的結果以p標籤的形式展現
{{ form_obj.as_ul}}//as_p 是會把你的結果以ul標籤的形式展現

這種方式的封裝程度擡高了,標籤的樣式以及參數不方便調整,可擴展性差,不推薦使用

第二種:

<p>
  {{ form_obj.username.label }}{{ form_obj.username }}
</p>
<p>
  {{ form_obj.password.label }}{{ form_obj.password }}
</p>
<p>
  {{ form_obj.email.label }}{{ form_obj.email }}
</p>

這種方式擴展性高,可是須要手寫大量代碼,因此也不推薦。

第三種:(推薦)

{% for foo in form_obj %}
<p>{{ foo.label }}{{ foo }}</p>
{% endfor %}

代碼量和擴展性都很高(推薦使用)

展現錯誤信息

首先咱們要把前端對咱們作的校驗取消掉,也就是瀏覽器,他會自動幫你作校驗,怎麼說呢,就是,若是你設置了最長的用戶名爲8位,這時候你是不能輸入超越8位的字符的,會直接卡在那裏,因此咱們要取消前端幫咱們作的校驗,只須要在form表單中添加一個參數novalida 就能夠了。

<form action="" method="post" novalidate>
    
展現錯誤信息   用對象點errors.0
<form action="" method="post" novalidate>
    {% for foo in form_obj %}
    <p>
        {{ foo.label }}:{{ foo }}
        <span style="color: red">{{ foo.errors.0 }}</span>
    </p>
    {% endfor %}
    <input type="submit">
</form>

解題

這個時候把咱們的代碼寫上去,來解上面的題:

後端代碼:

from django import forms
from django.forms import widgets
class MyRegForm(forms.Form):
    username = forms.CharField(min_length=3,max_length=8,label='用戶名',
                         #error_messages的做用是不符合條件的時候對應的錯誤信息
                               error_messages={
                                   'min_length':'用戶名最短爲三位',
                                   'max_length':'用戶名最短爲三位',
                                   'required':'用戶名不能爲空',
                               },initial='我是初始值',required=False,
                               #widget的做用是能夠給標籤加上樣式
                               widget=widgets.TextInput(attrs={'class':'form-control others'})
                               )
    password = forms.CharField(min_length=3,max_length=8,label='密碼',
                               error_messages={
                                   'min_length': '密碼最短爲三位',
                                   'max_length': '密碼最短爲三位',
                                   'required': '密碼不能爲空',
                               },widget=widgets.PasswordInput())
    confirm_password = forms.CharField(min_length=3, max_length=8, label='確認密碼', error_messages={
        'min_length': '確認密碼最短三位',
        'max_length': '確認密碼最長八位',
        'required': '確認密碼不能爲空'
    })
    email = forms.EmailField(label='郵箱',error_messages={
            'required':'郵箱不能爲空',
            'invalid':'郵箱格式不正確'
    },required=False,widget=widgets.EmailInput(attrs={'class':'form-control'}))

    def clean_username(self):
        username = self.cleaned_data.get('username')
        if 'xxx' in username:
            self.add_error('username','不能')
        return username

    def clean(self):
        password = self.cleaned_data.get('password')
        confirm_password = self.cleaned_data.get('confirm_password')
        if not password == confirm_password:
            self.add_error('confirm_password','兩次密碼不一致')
        return self.cleaned_data

  

def formmm(request):
    form_obj = MyRegForm()
    if request.method == 'POST':
        #這個對象只能穿字典過去,而咱們的request.POST正好是一個字典,因此直接傳進         去就行了。
        form_obj = MyRegForm(request.POST)
        if form_obj.is_valid():
            return HttpResponse('數據沒問題')
    return render(request,'formmm.html',locals())

前端代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<form action="" method="post" novalidate>
    {% for foo in form_obj %}
    <p>
        {{ foo.label }}:{{ foo }}
        <span style="color: red">{{ foo.errors.0 }}</span>
    </p>
    {% endfor %}
    <input type="submit">
</form>
</body>
</html>

forms組件鉤子函數

鉤子函數就是 針對字段 你還能夠作額外的校驗。

鉤子有分紅局部鉤子和全局鉤子

咱們以前的用戶名中不能有 ‘xxx’ 就是用鉤子函數實現的,把它拉過來看一下。

# 當你須要對某一個字段數據進行額外的一些列校驗 你能夠考慮使用鉤子函數
            # 針對單個字段的  使用局部鉤子
def clean_username(self):
    #對象裏有cleaned_data這個屬性,拿到了裏面的username來看一下
        username = self.cleaned_data.get('username')
        if 'xxx' in username:
            #不符合的話就丟進 error 裏面去
            self.add_error('username','不能')
        return username #鉤子勾過來了,固然要還回去了

 # 針對多個字段的校驗 使用全局鉤子      eg:校驗兩次密碼是否一致       
    def clean(self):
        password = self.cleaned_data.get('password')
        confirm_password = self.cleaned_data.get('confirm_password')
        if not password == confirm_password:
            self.add_error('confirm_password','兩次密碼不一致')
        return self.cleaned_data #這裏索性就把所有都還回去了。

如何改變inpu框的type屬性值

如何改變input框的type屬性值
        widget= widgets.TextInput()
        widget=widgets.PasswordInput()
    如何讓forms組件渲染出來的input框有form-control類屬性
        widget= widgets.TextInput(attrs={'class':'form-control others'})  # 若是有多個類屬性 空格隔開
        widget=widgets.PasswordInput(attrs={'class':'form-control others'})

每一個字段 還支持正則校驗
from django import forms
from django.forms import Form
from django.core.validators import RegexValidator
class MyForm(Form):
user = forms.CharField(
validators=[RegexValidator(r'^[0-9]+$', '請輸入數字'), RegexValidator(r'^159[0-9]+$', '數字必須以159開頭')],
)

補充知識

gender = forms.ChoiceField(
        choices=((1, "男"), (2, "女"), (3, "保密")),
        label="性別",
        initial=3,
        widget=widgets.RadioSelect()
    )


    hobby = forms.ChoiceField(
        choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),),
        label="愛好",
        initial=3,
        widget=widgets.Select()
    )

    hobby1 = forms.MultipleChoiceField(
        choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),),
        label="愛好",
        initial=[1, 3],
        widget=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()
    )
相關文章
相關標籤/搜索