1. 程式人生 > 其它 >Django中Form元件

Django中Form元件

目錄

Forms元件

1.基本使用

# 在views.py中

from django import forms

class MyForm(forms.Form):
    # username字串型別最小3位最大8位
    username = forms.CharField(min_length=3, max_length=8, label='使用者名稱')
    # password字串型別最小3位最大8位
    password = forms.CharField(min_length=3, max_length=8, label='密碼')
    # email欄位必須符合郵箱格式 [email protected]
    email = forms.EmailField(label='郵箱')
    
'''
label屬性預設展示的是類中定義欄位首字母大寫的形式
也可以自己修改 直接給欄位物件加label屬性即可
'''

2.校驗資料

在pycharm中的下方也可以測試資料

from app01 import views
# 1 將帶校驗的資料組織成字典的形式傳入即可
form_obj = views.MyForm({'username':'jason','password':'123','email':'123'})
# 2 判斷資料是否合法		注意該方法只有在所有的資料全部合法的情況下才會返回True
form_obj.is_valid()
False
# 3 檢視所有校驗通過的資料
form_obj.cleaned_data
{'username': 'jason', 'password': '123'}
# 4 檢視所有不符合校驗規則以及不符合的原因
form_obj.errors
{
  'email': ['Enter a valid email address.']
}
# 5 校驗資料只校驗類中出現的欄位 多傳不影響 多傳的欄位直接忽略
form_obj = views.MyForm({'username':'jason','password':'123','email':'[email protected]','hobby':'study'})
form_obj.is_valid()
True
# 6 校驗資料 預設情況下 類裡面所有的欄位都必須傳值
form_obj = views.MyForm({'username':'jason','password':'123'})
form_obj.is_valid()
False
"""
也就意味著校驗資料的時候 預設情況下資料可以多傳但是絕不可能少傳
"""

3.渲染標籤

form元件只會自動幫你渲染獲取使用者輸入的標籤(input select radio checkbox) 不能幫你渲染提交按鈕

後端

def index(request):
    # 1 生成一個空物件
    forms_obj = MyForm()
    # 2 直接將該空物件傳遞給html頁面
    return render(request, 'index.html', locals())

前端

<form action="" method="post">
    <p>第三種渲染方式(推薦使用)</p>
    {% for form in forms_obj %}
        <p>{{ form.label }}:{{ form }}</p>
    {% endfor %}
"""
label屬性預設展示的是類中定義的欄位首字母大寫的形式
也可以自己修改 直接給欄位物件加label屬性即可
	 username = forms.CharField(min_length=3,max_length=8,label='使用者名稱')
"""

展示錯誤提示資訊

瀏覽器會自動幫你校驗資料 但是前端的校驗弱不禁風 所以這裡我們去掉瀏覽器的自動校驗

<form action="" method="post" novalidate>  加個novalidate就行了

後端

def index(request):
    # 1 先產生一個空物件
    form_obj = MyForm()
    if request.method == 'POST':
        # 獲取使用者資料並且校驗
        """
        1.資料獲取繁瑣
        2.校驗資料需要構造成字典的格式傳入才行
        ps:但是request.POST可以看成就是一個字典
        """
        # 3.校驗資料
        form_obj = MyForm(request.POST)  # 
        # 4.判斷資料是否合法
        if form_obj.is_valid():
            # 5.如果合法 操作資料庫儲存資料
            return HttpResponse('OK')
        # 5.不合法 有錯誤
    # 2 直接將該空物件傳遞給html頁面
    return render(request,'index.html',locals())

必備的條件

1.get請求和post請求傳給html頁面物件變數名必須一樣(上面的form_obj)

2.forms元件當你的資料不合法的情況下,會儲存你上次的資料,讓你基於之前的

結果進行修改,更加的人性化

前端

<form action="" method="post" novalidate>
    <p>第三種渲染方式(推薦使用)</p>
    {% for form in forms_obj %}
        <p>{{ form.label }}:{{ form }}
            <span style="color: red">{{ form.errors.0 }}</span>  # 這裡的errors後必須加0,不然會換行
        </p>
    {% endfor %}
    <input type="submit">
</form>

修改錯誤資訊

class MyForm(forms.Form):
    # username字串型別最小3位最大8位
    username = forms.CharField(min_length=3,max_length=8,label='使用者名稱',
                               error_messages={
                                   'min_length':'使用者名稱最少3位',
                                   'max_length':'使用者名稱最大8位',
                                   'required':"使用者名稱不能為空"
                               }
                               )
    # password字串型別最小3位最大8位
    password = forms.CharField(min_length=3,max_length=8,label='密碼',
                               error_messages={
                                   'min_length': '密碼最少3位',
                                   'max_length': '密碼最大8位',
                                   'required': "密碼不能為空"
                               }
                               )
    # email欄位必須符合郵箱格式  [email protected]
    email = forms.EmailField(label='郵箱',
                             error_messages={
                                 'invalid':'郵箱格式不正確',
                                 'required': "郵箱不能為空"
                             }
                             )

鉤子函式(HOOK)

鉤子函式再forms元件中就類似於第二道關卡,能夠讓我們自定義校驗規則(比如正則)

型別 使用規則
區域性鉤子 當你需要給單個欄位增加校驗規則的時候可以使用
全域性鉤子 當你需要給多個欄位增加校驗規則的時候可以使用
鉤子函式是寫在類裡面的

# 區域性鉤子
    def clean_username(self):
        # 獲取到使用者名稱
        username = self.cleaned_data.get('username')
        # 判斷是否合法
        if '666' in username:
            # 前端展示錯誤資訊(比如這裡可以寫正則來校驗)
            self.add_error('username', '不要給我加666!!!')
        # 將鉤子函式勾取出來的資料再放回去
        return username

    # 全域性鉤子
    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

forms元件其他引數及補充知識點

label		欄位名
error_messages  自定義報錯資訊
initial  預設值
required  控制欄位是否必填

給input框新增樣式和屬性值

"""
1.欄位沒有樣式
2.針對不同型別的input如何修改
	text
	password
	date
	radio
	checkbox
	...
"""
widget=forms.widgets.PasswordInput(attrs={'class':'form-control c1 c2','username': 'jason'})
# 多個屬性值的話 直接空格隔開即可
部落格最後還有其他type型別渲染

第一道關卡正則校驗

# 先匯入模組
from django.core.validators import RegexValidator

phone = forms.CharField(
        validators=[
            RegexValidator(r'^[0-9]+$', '請輸入數字'),
            RegexValidator(r'^159[0-9]+$', '數字必須以159開頭')
        ],
    )

其他型別渲染

# radio
    gender = forms.ChoiceField(
        choices=((1, "男"), (2, "女"), (3, "保密")),
        label="性別",
        initial=3,
        widget=forms.widgets.RadioSelect()
    )
# select
    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()
    )
# 單選checkbox
    keep = forms.ChoiceField(
        label="是否記住密碼",
        initial="checked",
        widget=forms.widgets.CheckboxInput()
    )
# 多選checkbox
    hobby2 = forms.MultipleChoiceField(
        choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),),
        label="愛好",
        initial=[1, 3],
        widget=forms.widgets.CheckboxSelectMultiple()
    )

form元件原始碼

切入點:

form_obj.is_valid()

"""
切入點:
	form_obj.is_valid()
"""
def is_valid(self):
        """
        Returns True if the form has no errors. Otherwise, False. If errors are
        being ignored, returns False.
        """
   return self.is_bound and not self.errors
   # 如果is_valid要返回True的話 那麼self.is_bound要為True self.errors要為Flase
  
  
self.is_bound = data is not None or files is not None  # 只要你傳值了肯定為True


@property
def errors(self):
        "Returns an ErrorDict for the data provided for the form"
        if self._errors is None:
            self.full_clean()
        return self._errors

# forms元件所有的功能基本都出自於該方法
def full_clean(self):
  	self._clean_fields()  # 校驗欄位 + 區域性鉤子
    self._clean_form()  # 全域性鉤子
    self._post_clean()