1.多對多表的建立方式
2.forms組件
3.session 與 cookie
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等方法;
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表中,保存的數據 能夠在後端任意位置獲取到