多對多表的建立方式 forms組件 session與cookie

1.多對多表的建立方式 
2.forms組件
3.session 與 cookie
1.多對多表的建立方式
1.全自動(推薦使用*)
class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8,decimal_places=2)
    authors = models.ManyToManyField(to='Author')

class Author(models.Model):
    name = models.CharField(max_length=32)

2.純手動(瞭解便可)
class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8,decimal_places=2)

class Author(models.Model):
    name = models.CharField(max_length=32)
        
class Book2Author(models.Model):
    book = models.ForeignKey(to='Book')
    author = models.ForeignKey(to='Author')
    create_time = models.DateField(auto_now_add=True)

3.半自動(推薦使用******)    
class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8,decimal_places=2)
    authors = models.ManyToManyField(to='Author',through='Book2Author',through_fields=('book','author'))
    # through 告訴django orm 書籍表和做者表的多對多關係是經過Book2Author來記錄的
    # through_fields 告訴django orm記錄關係時用過Book2Author表中的book字段和author字段來記錄的
    
class Author(models.Model):
    name = models.CharField(max_length=32)
    # books = models.ManyToManyField(to='Book', through='Book2Author', through_fields=('author', 'book'))

class Book2Author(models.Model):
    book = models.ForeignKey(to='Book')
    author = models.ForeignKey(to='Author')
    create_time = models.DateField(auto_now_add=True)

三種方式的優缺點:
 1.全自動
  優勢:不須要你手動建立第三張表;
  缺點:關係表中擴展性差,字段是固定的;
2.全手動
  優勢:擴展性高,關係表中能夠任意的擴展字段;
  缺點:orm查詢不方便;
3.半自動
  優勢:集全自動和純手動的兩個優勢,
  缺點:對於多對多字段;再也不支持add,set,remove,clear等方法;
forms組件
1.forms組件可以直接完成如下的三步操做
        1.渲染前端頁面
	2.校驗數據是否合法
	3.展現錯誤信息  
1.寫一個基礎了forms.Form的類
    from django import forms
    class LoginForm(forms.Form):
        username = forms.CharField(max_length=8,min_length=3)  # 用戶名最長八位最短三位
        password = forms.CharField(max_length=8,min_length=5)  # 密碼最長八位最短五位
        email = forms.EmailField()  # email必須是郵箱格式

2.基本使用
    from app01 import views
    1.將須要校驗的數據 以字典的方式傳遞給自定義的類 實例化產生對象
        form_obj = views.LoginForm({'username':'jason','password':'123','email':'123'})
    2.如何查看數據是否所有合法
        form_obj.is_valid()  # 只有全部的數據都符合要求 纔會是True
        False
    3.如何查看錯誤緣由
        form_obj.errors
        {
        'password': ['Ensure this value has at least 5 characters (it has 3).'], 
        'email': ['Enter a valid email address.']
        }
    4.如何查看經過校驗的數據
        form_obj.cleaned_data  
        {'username': 'jason'}

    注意事項:
        1.自定義類中全部的字段默認都是必需要傳值的
        2.能夠額外傳入類中沒有定義的字段名 forms組件不會去校驗 也就意味着多傳一點關係沒有
        form_obj = views.LoginForm({'username':'jason','password':'123456','email':'123@qq.com'})
        form_obj.is_valid()
        True
        
        form_obj = views.LoginForm({'username':'jason','password':'123456'})
        form_obj.is_valid()
        False
        
        form_obj = views.LoginForm({'username':'jason','password':'123456','email':'123@qq.com','hobby':'read'})
        form_obj.is_valid()
        True

2.渲染頁面
三種方式
    <p>第一種渲染頁面的方式(封裝程度過高 通常只用於本地測試  一般不適用)</p>
    {{ form_obj.as_p }}  
    {{ form_obj.as_ul }}
    {{ form_obj.as_table }}
    
    <p>第二種渲染頁面的方式(可擴展性較高 書寫麻煩)</p>
    <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>
    
    <p>第三種渲染頁面的方式(推薦)</p>
    {% for foo in form_obj %}
        <p>{{ foo.label }}{{ foo }}</p>
    {% endfor %}
注意事項
    1.forms組件在幫你渲染頁面的時候 只會渲染獲取用戶輸入的標籤  提交按鈕須要你手動添加    
    2.input框的label註釋  不指定的狀況下 默認用的類中字段的首字母大寫    
    3.校驗數據的時候能夠先後端都校驗 作一個雙重的校驗,可是前端的校驗無關緊要 然後端的校驗則必需要有,由於前端的校驗能夠經過爬蟲直接避開
前端
  4.取消瀏覽器校驗功能,form標籤指定novalidate屬性便可
<form action="" method='post' novalidate></form> 3.展現錯誤信息 {% for foo in form_obj %} <p>{{ foo.label }}:{{ foo }} <span>{{ foo.errors.0 }}</span> </p> {% endfor %} 後端代碼 password = forms.CharField(max_length=8,min_length=5,label='密碼',error_messages={ 'max_length':'密碼最大八位', 'min_length':'密碼最小五位', 'required':'密碼不能爲空' },required=False,validators=[RegexValidator(r'^[0-9]+$', '請輸入數字'),
           RegexValidator(r'^159[0-9]+$', '數字必須以159開頭')]) # 密碼最長八位最短五位 4.鉤子函數(HOOK) forms組件暴露給用戶 能夠自定義的校驗規則 用法:在自定義的form類中書寫方法便可 # 局部鉤子(針對某一個字段作額外的校驗) 校驗用戶名中不能包含666 一旦包含 提示 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') confirm_password = self.cleaned_data.get('confirm_password') if not password == confirm_password: self.add_error('confirm_password','兩次密碼不一致') return self.cleaned_data
5.forms組件其餘字段及操做方式 required 是否必填 label 註釋信息 error_messages 報錯信息 initial 默認值 widget 控制標籤屬性和樣式 widget=widgets.PasswordInput() 控制標籤屬性 widget=widgets.PasswordInput(attrs={'class':'form-control c1 c2','username':'jason'}) 其餘字段瞭解知識點(知道有這些對象 須要用到的時候 可以知道去哪找) # 單選的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() ) # 多選的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() )
cookie與session
    因爲http協議是無狀態的 沒法記錄用戶狀態 
    
    cookie就是保存在客戶端瀏覽器上的鍵值對
        工做原理:當你登錄成功以後 瀏覽器上會保存一些信息
        下次再訪問的時候 就會帶着這些信息去訪問服務端  服務端經過這些信息來識別出你的身份
        
        cookie雖然是寫在客戶端瀏覽器上的  可是是服務端設置的
        瀏覽器能夠選擇不服從命令 禁止寫cookie
        
    
    session就是保存在服務器上的鍵值對
        session雖然是保存在服務器上的鍵值對
        可是它是依賴於cookie工做的
        
        服務端返回給瀏覽器一個隨機的字符串
        瀏覽器以鍵值對的形式保存
        sessionid:隨機字符串
        
        瀏覽器在訪問服務端的時候  就會將隨機字符串攜帶上
        後端獲取隨機串與後端的記錄的作比對
            隨機字符串1:數據1
            隨機字符串2:數據2
        
如何操做Cookie
    django返回給客戶端瀏覽器的都必須是HttpResponse對象
    return HttpResponse()
    return render()
    return redirect()
        
    obj1 = HttpResponse()
    return obj1
    obj2 = render()
    return obj2
    obj3 = redirect()
    return obj3
    
        
    設置cookie利用的就是HttpResponse對象
        obj1.set_cookie('k1','v1')
    
    獲取cookie
        request.COOKIE.get()
    
    刪除cookie
        obj1.delete_cookie("k1")
    
    設置超時時間
        max_age=None, 超時時間
        expires=None, 超時時間(IE requires expires, so set it if hasn't been already.)
    
    登錄功能
        
    
session
    設置session
        request.session['name'] = 'jason'
        """
        上面這一句話發生了三件事
            1.django 內部自動生成一個隨機字符串
            2.將隨機字符串和你要保存的數據 寫入django_session表中(如今內存中生成一個緩存記錄 等到通過中間件的時候纔會執行)
            3.將產生的隨機字符串發送給瀏覽器寫入cookie
                sessionid:隨機字符串
        """
    獲取session
        request.session.get('name')
        """
        上面這一句話發生了三件事
            1.django內部會自動從請求信息中獲取到隨機字符串
            2.拿着隨機字符串去django_session表中比對
            3.一旦對應上了就將對應的數據解析出來放到request.session中
        
        """
    
    django session默認的超時時間是14天
    
    
    django_session表中的一條記錄針對一個瀏覽器
    
    
    # 刪除當前會話的全部Session數據
    request.session.delete()  # 刪除的是瀏覽器的sessionid信息
      
    # 刪除當前的會話數據並刪除會話的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失效策略。

總結:你在後期能夠將一些數據保存到session表中,保存的數據 能夠在後端任意位置獲取到
相關文章
相關標籤/搜索