文章目錄
Form組件
form組件的主要功能如下:
- 渲染標籤
- 校驗數據
- 展示信息
校驗數據
第一步首先要導入forms模塊,並定義一個form類
from django import forms
class MyForm(forms.Form):
name = forms.CharField(max_length=6)
password = forms.CharField(max_length=8, min_length=3)
email = forms.EmailField(required=True)
第二步實例化form對象
form_obj = MyForm({
'name': 'linwow1',
'password': '12'
'email': 'linwow.com'
})
第三步查看數據校驗是否合法
form_obj.is_valid() # 只有當所有的字段都校驗通過纔會返回True
第四步查看校驗錯誤的信息
form_obj.errors # 這個裏面放的是所有校驗未通過的字段及錯誤提示
"""
{
'name': ['Ensure this value has at most 6 characters (it has 7).'],
'password': ['Ensure this value has at least 3 characters (it has 2).'],
'email': ['Enter a valid email address.']
}
"""
第五步查看校驗通過的數據
form_obj.cleaned_data # 符合校驗規則數據都會被放到該對象中
ps:
form組件校驗數據的規則從上往下依次取值校驗
校驗通過的放到cleaned_data
校驗失敗的放到errors
注意:
form中所有的字段默認都是必須傳值的(required=True);
校驗數據的時候可以傳入多個值,多傳的數據不會做任何的校驗 ,不會影響form校驗規則。
渲染標籤
form組件可以渲染獲取用戶輸入的標籤, 但是不會渲染提交按鈕,需要手動添加。form組件提交數據如果數據不合法,頁面上會保留之前用戶輸入的信息。
第一種渲染方式
<h1> 第一種渲染方式(可擴展性較差) </h1>
{{form_obj.as_p}}
as_p指點被p標籤包裹,比如as_ul是配ul包裹
第二種渲染方式
<h1> 第二種渲染方式 </h1>
<form action = "">
<p> {{form_obj.name.label}} {{form_obj.name}} </p>
<p> {{form_obj.password.label}} {{form_obj.password}} </p>
<p> {{form_obj.email.label}} {{form_obj.email}} < / p >
<input type="submit"></form>
第三種渲染標籤的方式
<h1> 第三種渲染標籤的方式 </h1>
<form action="" method="post" novalidate>
{% for foo in form_obj %}
<p> {{foo.label}} {{foo}} <span>{{ foo.errors.0 }}</span></p>
{ % endfor %}
</form>
novalidate是爲了告訴前端不進行校驗
注意:在使用form組件對模型表進行數據校驗的時候,只需要保證字段一致,那麼在數據庫創建的對象的時候你就可以直接使用 **form_obj.cleaned_data
設置標籤樣式
from django import forms
from django.forms import widgets
password = forms.CharField(max_length=8,min_length=3,error_messages={
'max_length': '密碼最長8位',
'required': '密碼不能爲空',
'min_length':'密碼最少3位'
},widget=widgets.PasswordInput(attrs={'class':'c1 form-control'}))
鉤子函數
在Fom類中定義 clean_字段名() 方法,就能夠實現對特定字段進行校驗。
class MyForm(forms.Form):
name = forms.CharField(max_length=6,label='用戶名',error_messages={
'max_length':'用戶名最長6位',
'required':'用戶名不能爲空'
})
password = forms.CharField(max_length=8,min_length=3,error_messages={
'max_length': '密碼最長8位',
'required': '密碼不能爲空',
'min_length':'密碼最少3位'
},widget=widgets.PasswordInput(attrs={'class':'c1 form-control'}))
confirm_password = forms.CharField(max_length=8, min_length=3, error_messages={
'max_length': '確認密碼最長8位',
'required': '確認密碼不能爲空',
'min_length': '確認密碼最少3位'
},widget=widgets.PasswordInput())
email = forms.EmailField(error_messages={
'invalid':'郵箱格式不正確',
'required':'郵箱不能爲空'
})
局部鉤子函數(單個字段的校驗利用局部鉤子函數)
def clean_name(self):
name = self.cleaned_data.get('name')
if 'sb' in name:
self.add_error('name', '用戶名中不能包含敏感詞彙!')
return name # return還是要加上的,兼容性考慮
全局鉤子函數 (多個字段的校驗利用全局鉤子函數)
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
常用字段和插件
創建Form類時,主要涉及到 【字段】 和 【插件】,字段用於對用戶請求數據的驗證,插件用於自動生成HTML;
initial
初始值,input框裏面的初始值。
class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用戶名",
initial="張三" # 設置默認值
)
pwd = forms.CharField(min_length=6, label="密碼")
error_messages
重寫錯誤信息。
class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用戶名",
initial="張三",
error_messages={
"required": "不能爲空",
"invalid": "格式錯誤",
"min_length": "用戶名最短8位"
}
)
pwd = forms.CharField(min_length=6, label="密碼")
password
class LoginForm(forms.Form):
...
pwd = forms.CharField(
min_length=6,
label="密碼",
widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True)
)
radioSelect
單radio值爲字符串
class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用戶名",
initial="張三",
error_messages={
"required": "不能爲空",
"invalid": "格式錯誤",
"min_length": "用戶名最短8位"
}
)
pwd = forms.CharField(min_length=6, label="密碼")
gender = forms.fields.ChoiceField(
choices=((1, "男"), (2, "女"), (3, "保密")),
label="性別",
initial=3,
widget=forms.widgets.RadioSelect()
)
單選Select
class LoginForm(forms.Form):
...
hobby = forms.ChoiceField(
choices=((1, "籃球"), (2, "足球"), (3, "雙色球"), ),
label="愛好",
initial=3,
widget=forms.widgets.Select()
)
多選Select
class LoginForm(forms.Form):
...
hobby = forms.MultipleChoiceField(
choices=((1, "籃球"), (2, "足球"), (3, "雙色球"), ),
label="愛好",
initial=[1, 3],
widget=forms.widgets.SelectMultiple()
)
單選checkbox
class LoginForm(forms.Form):
...
keep = forms.ChoiceField(
label="是否記住密碼",
initial="checked",
widget=forms.widgets.CheckboxInput()
)
多選checkbox
class LoginForm(forms.Form):
...
hobby = forms.MultipleChoiceField(
choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),),
label="愛好",
initial=[1, 3],
widget=forms.widgets.CheckboxSelectMultiple()
)
cookie
Cookie具體指的是一段小信息,它是服務器發送出來存儲在瀏覽器上的一組組鍵值對,下次訪問服務器時瀏覽器會自動攜帶這些鍵值對,以便服務器提取有用信息。
cookie的工作原理是:由服務器產生內容,瀏覽器收到請求後保存在本地;當瀏覽器再次訪問時,瀏覽器會自動帶上Cookie,這樣服務器就能通過Cookie的內容來判斷這個是“誰”了。
設置cookie
obj.set_cookie() # 給瀏覽器設置cookie
獲取cookie
request.COOKIE.get('name')
request.COOKIE['name']
示例
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'linwow' and password == '123':
old_path = request.GET.get('next')
if old_path:
obj = redirect(old_path)
else:
obj = redirect('/home/')
# 用戶登錄成功 朝瀏覽器設置一個cookie
obj.set_cookie('name', 'linwow', expires=7 * 24 * 3600)
return obj
return render(request, 'login.html')
from functools import wraps
def login_auth(func):
@wraps(func)
def inner(request, *args, **kwargs):
# 校驗cookie
# print(request.get_full_path())
old_path = request.get_full_path()
if request.COOKIES.get('name'):
return func(request, *args, **kwargs)
return redirect('/login/?next=%s' % old_path)
return inner
def logout(request):
rep = redirect("/login/")
rep.delete_cookie("name") # 刪除用戶瀏覽器上之前設置的usercookie值
return rep
session
設置session
request.session['name'] = 'linwow'
- 首先生成一個隨機的字符串
- 在django session表中存儲該隨機字符串與數據的記錄
- 將隨機的字符串發送給客戶端瀏覽器
獲取session
request.session.get('name')
- django自動獲取瀏覽器隨機字符串取django session表裏面比對(瀏覽器會設置一個鍵爲sessionid來存放session值)
- 如果比對成功 會將當前隨機字符串對應的數據賦值給request.session
- 通過request.session操作該數據(數據不存在也不會影響我們的業務邏輯)
刪除當前會話的所有Session數據
request.session.delete()
刪除當前的會話數據並刪除會話的Cookie。
request.session.flush()
這用於確保前面的會話數據不可以再次被用戶的瀏覽器訪問
例如,django.contrib.auth.logout()
函數中就會調用它。
設置會話Session和Cookie的超時時間
request.session.set_expiry(value)
--如果value是個整數,session會在些秒數後失效。
--如果value是個datatime或timedelta,session就會在這個時間後失效。
--如果value是0, 用戶關閉瀏覽器session就會失效。
--如果value是None, session會依賴全局session失效策略。
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
pwd = request.POST.get('pwd')
if username == 'linwow' and pwd == '123':
old_path = request.GET.get('next')
if old_path:
obj = redirect(old_path)
else:
obj = redirect('/home/')
request.session['name'] = 'linwow'
return obj
return render(request,'login.html')
from functools import wraps
def login_auth(func):
@wraps(func)
def inner(request,*args,**kwargs):
old_path = request.get_full_path()
if request.session.get('name'):
return func(request,*args,**kwargs)
return redirect('/login/?next=%s' % old_path)
return inner
@method_decorator(login_auth,name='get') 第二種裝飾指定的方法,name參數必須指定
class MyHome(View):
@method_decorator(login_auth) 第三種get和post都會被裝飾
def dispatch(self, request, *args, **kwargs):
super().dispatch(request,*args,**kwargs)
@method_decorator(login_auth) 第一種只裝飾get請求
def get(self,request):
return HttpResponse('get')
def post(self,request):
return HttpResponse('post')