小談Django中的form元件
阿新 • • 發佈:2020-10-12
form
簡單Form示例
定義
from django import forms
class RegForm(forms.Form):
user = forms.CharField(label="賬號")
pwd = forms.CharField(label="密碼", widget=forms.PasswordInput)
使用
檢視函式
def reg(request): form_obj = RegForm() if request.method == 'POST': form_obj = RegForm(request.POST) if form_obj.is_valid(): print(request.POST) # 上面的顯示結果: # <QueryDict: {'csrfmiddlewaretoken': ['wFp3cnKRpV1ZMuOdZl0rklwWkncSfULWeWaDPhaBa9eObp0Vnl4JBgZqj7MJuy4t'], 'user': ['alex'], 'pwd': ['123']}> print(form_obj.cleaned_data, type(form_obj.cleaned_data)) # 上面的顯示結果: # {'user': 'alex', 'pwd': '123'} <class 'dict'> return HttpResponse('註冊成功') return render(request, 'reg.html', {'form_obj': form_obj})
模板
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="" method="post" novalidate> {% csrf_token %} {# {{ form_obj.as_p }}#} <p> <label for="{{ form_obj.user.id_for_label }}">{{ form_obj.user.label }}</label> {{ form_obj.user }} <span>{{ form_obj.user.errors.0 }}</span> </p> <p> <label for="{{ form_obj.pwd.id_for_label }}">{{ form_obj.pwd.label }}</label> {{ form_obj.pwd }} </p> {{ form_obj.errors }} <button>註冊</button> </form> </body> </html>
模板更多
- forms.Charfield --> 欄位物件
- widget --> 外掛物件
生成所有欄位的input框
{{ form_obj.as_p }}
生成某個欄位的input框
{{ form_obj.user }}
某個欄位的中文提示
{{ form_obj.user.label }}
某個欄位的input框的ID
{{ form_obj.user.id_for_label }}
生成單個的input框並且設定label標籤
<p> <label for="{{ form_obj.user.id_for_label }}">{{ form_obj.user.label }}</label> {{ form_obj.user }} </p> <label for="{{ form_obj.user.id_for_label }}"> -> 作用: 讓input框聚焦 -> 滑鼠點選"賬號"游標自動切到input框中
所有欄位的校驗錯誤
{{ form_obj.errors }} -> 所有欄位的所有錯誤
{{ form_obj.errors.0 }} -> 所有欄位的第一個錯誤
某個欄位的校驗錯誤
{{ form_obj.user.errors }} -> 某個欄位的所有錯誤
{{ form_obj.user.errors.0 }} -> 某個欄位的第一個錯誤
widget=forms.PasswordInput
# input框顯示密文
class RegForm(forms.Form)L
...
pwd = forms.CharField(label='密碼', widget=forms.PasswordInput)
Form常用欄位和外掛
- 欄位用於對使用者請求資料的驗證 __> 與form表單校驗相關
- 外掛用於自動生成HTML __> 和前段渲染相關
所有欄位
# 匯入forms模組語句:
# from django import forms
# 直接點進forms有下面這句, 然後點進去fields看
from django.forms.fields import *
# 看到所有的欄位:
__all__ = (
'Field', 'CharField', 'IntegerField',
'DateField', 'TimeField', 'DateTimeField', 'DurationField',
'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField',
'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField',
'ComboField', 'MultiValueField', 'FloatField', 'DecimalField',
'SplitDateTimeField', 'GenericIPAddressField', 'FilePathField',
'SlugField', 'TypedChoiceField', 'TypedMultipleChoiceField', 'UUIDField',
)
常用欄位只寫了三個 ; 如果樣式不夠 , 可以修改widget就可以了 , 可以點出很多東西
- 比如ChoiceField(widget=forms.RadioSelect)
- 比如MultipleChoiceField(widget=forms.CheckboxSelectMultiple)
Charfield
user = forms.CharField(label="賬號")
ChoiceField
gender = forms.ChoiceField(choices=(('1','男'),('2','女')),label='性別')
MultipleChoiceField
hobby = forms.MultipleChoiceField(choices=(('1','抽菸'),('2','喝酒'),('3','吐口水')), label='愛好')
inital
class RegForm(forms.Form):
gender = forms.ChoiceField(choices=(('1','男'),('2','女')),label='性別', initial='2') # 設定預設值, 渲染在前段頁面就是input框中value的值
error_messages
class RegForm(forms.Form):
user = forms.CharField(
label="賬號",
min_length=6,
# 在前段顯示錯誤的資訊; 如果不設定, 顯示的是預設的,英文的
error_messages={
'required': '不能為空!',
'min_length':'至少是6位!'
}
)
widget
# 前段的input框顯示密文
class RegForm(forms.Form)L
...
pwd = forms.CharField(label='密碼', widget=forms.PasswordInput)
# widget=forms.PasswordInput
# 上下兩個一樣,主要看點進去"from django import forms"中的forms,看模組如何匯入的.
# widget=forms.widgets.PasswordInput
required
class RegForm(forms.Form):
user = forms.CharField(
# required預設是True_>必填的;改成False可以不填
required=False,
label="賬號",
min_length=6,
# 在前段顯示錯誤的資訊; 如果不設定, 顯示的是預設的,英文的
error_messages={
'required': '不能為空!',
'min_length':'至少是6位!'
}
)
disabled
是否禁用
min_length
最小長度
choices
可選擇的資料
方法一 :
class RegForm(forms.Form):
...
gender = forms.ChoiceField(choices=(('1','男'),('2','女')),label='性別', initial='2')
hobby = forms.MultipleChoiceField(choices=(('1','抽菸'),('2','喝酒'),('3','吐口水')), label='愛好')
方法二 :
class RegForm(forms.Form):
...
gender = forms.ChoiceField(label='性別', initial='2')
def __init__(self, *args, **kwargs):
super(RegForm, self).__init__(*args, **kwargs)
# self.fields['gender'].choices = [('1','男'),('2','女')]
# 上下兩句效果一樣, 但是models中gender類得新增雙下str方法
self.fields['gender'].choices = models.gender.objects.all()
校驗
1. 自帶的校驗規則
各個欄位都有自己自帶的校驗規則 , 比如required...
2. 自定義校驗規則
1. 寫函式
from django import forms
from django.core.exceptions import ValidationError
# value就是input框中填寫的值
def check_name(value):
# 自定義校驗規則
# 如果校驗合格, 什麼都不做;
# 如果校驗不合格, 丟擲異常(ValidationError)
if 'alex' in value:
raise ValidationError('不能包含alex,非法字元!')
class RegForm(forms.Form):
user = forms.CharField(
label="賬號",
min_length=6,
# 自定義校驗規則
validators=[check_name]
error_messages={
'required': '不能為空!',
'min_length':'至少是6位!'
}
)
2. 內建校驗器
from django import forms
# RegexValidator是正則的內建校驗器,還有很多其他的, 比如: 郵箱的,url的,ipv6的,...;可以點進去看
from django.core.validators import RegexValidator
class RegForm(forms.Form):
phone = forms.Charfield(
# RegexValidator()例項化一個RegexValidator的物件,第一個引數是正則表示式; 第二個引數是錯誤資訊;
# 可以點進去看看, 還有其他的,一般這兩個就夠了
validators=[RegexValidator(r'^1[3-9]\d{9}$', '手機號格式不正確')]
)
3. 區域性鉤子
class RegForm(forms.Form):
user = forms.CharField(
label="賬號",
min_length=6,
error_messages={
'required': '不能為空!',
'min_length':'至少是6位!'
}
)
def clean_user(self):
# 區域性鉤子 clean_欄位名
# 如果校驗成功, 返回當前欄位的值;
# 如果校驗不成功, 丟擲異常;
if 'alex' in self.cleaned_data.get('user'):
raise ValidationError('不能包含alex,非法字元!')
return self.cleaned_data.get('user')
4. 全域性鉤子
class RegForm(forms.Form):
pwd = forms.CharField(label="密碼", widget=forms.PasswordInput)
re_pwd = forms.CharField(label="密碼", widget=forms.PasswordInput)
...
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:
# 這樣錯誤資訊就在re_pwd後面顯示了,不寫的話只會在所有欄位的所有錯誤中出現;
self.add_error('re_pwd','兩次密碼不一致!!!')
raise ValidationError('兩次密碼不一致!')
- 如果要定義的校驗規則只針對於一個欄位使用 __> 區域性鉤子 ;
- 如果要定義的校驗規則針對 一個Form中的兩個欄位合起來做校驗( 如密碼和確認密碼 ) __> 全域性鉤子 ;
- 如果要定義的校驗規則適用於多個欄位 __> 寫函式或者內建校驗器 , 可以只寫一次函式 , 然後把函式名寫到每個欄位的validators中 ;