Django 之 form組件、cookie、session

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')
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章