1、model經常使用操做html
一、13個API查詢:all,filter,get ,values,values_list,distinct,order_by ,reverse , exclude(排除),count,first,last,esits(判斷是否存在)python
須要掌握的all、values、values_listweb
all的性能是最低的正則表達式
二、only和defer數據庫
datalist = models.Userinfo.objects.all().only("name","email") #拿到的仍是一個QuerySet集合,僅僅取name和email for item in datalist: print(item.id) print(item.name) print(item.pwd) #只要表裏有這個字段,同樣會取到值,額外的會再發一次請求 datalist = models.Userinfo.objects.all().defer("name","email") #阻止,不取name和email for item in datalist: print(item.id) print(item.pwd)
注意:用only的話就去取only裏面的字段,取其它的字段效率過低了,儘量的少的鏈接數據庫django
三、路由系統瀏覽器
反向生成URL:服務器
有兩種方式:{% url 「a1」 %}session
reverse(「a1」)函數
用reverse須要導入: from django.core.urlresolvers import reverse
/index/ func name=a1 {% url "a1"} reverse('a1') /index/(\d+)/ func name=a2 {% url "a2" 11 %} reverse('a2',args=(11,)) /index/(?P<nid>\d+)/ func name=a3 {% url "a2" nid=11 %} reverse('a3',kwargs={'nid':11})
def index(request): if request.method == "POST": """ 兩個return是同樣的,用url反向解析就至關於下面的路徑在urls裏面 協商別名name="index",但在模板中仍是要用{%url"index"%} """ # return redirect(reverse(index)) return redirect("index.html") # 跳轉到我的主頁 return render(request, "hh.html")
四、Django的生命週期
web服務器網關接口(Python Web Server Gateway Interface,縮寫爲WSGI)
2、form組件
1、Form組件介紹
Form組件能夠作的幾件事情:
一、用戶請求數據驗證
二、自動生成錯誤信息
三、打包用戶提交的正確信息
四、若是其中有一個錯誤了,其餘的正確這,保留上次輸入的內容
四、自動建立input標籤並能夠設置樣式
2、Form組件的使用
一、建立規則
class Foo(Form) # 必須繼承 username = XXX password = XXX email = XXX 注意這裏的字段必須和input字段一致
二、數據和規則進行匹配
先導入view.py
from django.forms import Form from django.forms import fields from django.forms import widgets
# 一、建立規則 class TeacherForm(Form): # 必須繼承form # 建立字段,本質上是正則表達式 username = fields.CharField( required=True, # 必填字段 error_messages={"required": "用戶名不能爲空!"}, widget=widgets.TextInput(attrs={"placeholder": "用戶名","class": "form-control"}) # 自動生成input框 ) password = fields.CharField( required=True, error_messages={'required': '密碼不能爲空!'}, widget=widgets.TextInput(attrs={'placeholder': '密碼', 'class': 'form-control'}) ) email = fields.EmailField( required=True, error_messages={"requeired": "郵箱不能爲空!", "invalid": "無效的郵箱格式"}, widget=widgets.EmailInput(attrs={"placeholder":"郵箱", "class": "form-control"}) ) # 二、使用規則:將數據和規則進行匹配 def teacherindex(request): teacher_obj = models.UserInfo.objects.all() print(teacher_obj) return render(request, "teacherindex.html", {"teacher_obj": teacher_obj}) def add(request): if request.method == "GET": form = TeacherForm() # 只是顯示一個input框 return render(request, "add.html", {"form": form}) else: form = TeacherForm(data=request.POST) if form.is_valid(): # 開始驗證 form.cleaned_data['ut_id'] = 1 # 要分的清是班主任仍是講師 models.UserInfo.objects.all().create(**form.cleaned_data) return redirect("/teacherindex/") else: return render(request, "add.html", {"form": form})
add.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>添加老師信息</title> </head> <body> <form method="post" novalidate> {% csrf_token %} <p>姓名:{{ form.username }}</p>{{ form.errors.username.0 }} <p>密碼:{{ form.password }}</p>{{ form.errors.password.0 }} <p>郵箱:{{ form.email }}</p>{{ form.errors.email.0 }} <p><input type="submit" value="提交"></p> </form> </body> </html>
teacherindex.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8"> <table class="table-bordered table-striped"> <thead> <tr> <th>編號</th> <th>姓名</th> <th>郵箱</th> </tr> </thead> <tbody> {% for teacher in teacher_obj %} <tr> <td>{{ teacher.id }}</td> <td>{{ teacher.username }}</td> <td>{{ teacher.email }}</td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </body> </html>
若是訪問視圖的是一個GET
請求,它將建立一個空的表單實例並將它放置到要渲染的模板的上下文中。這是咱們在第一個訪問該URL 時預期發生的狀況。
若是表單的提交使用POST
請求,那麼視圖將再次建立一個表單實例並使用請求中的數據填充它:form = NameForm(request.POST)
。這叫作」綁定數據至表單「(它如今是一個綁定的表單)。
咱們調用表單的is_valid()
方法;若是它不爲True
,咱們將帶着這個表單返回到模板。這時表單再也不爲空(未綁定),因此HTML 表單將用以前提交的數據填充,而後能夠根據要求編輯並改正它。
若是is_valid()
爲True
,咱們將可以在cleaned_data
屬性中找到全部合法的表單數據。在發送HTTP 重定向給瀏覽器告訴它下一步的去向以前,咱們能夠用這個數據來更新數據庫或者作其它處理。
備註: form = TeacherForm() #沒有參數,只是一個input框
form = TeacherForm(data=request.POST) # 數據和規則放置一塊兒 (添加的時候用)
form = TeacherForm(initial={'username':obj.username,'password':obj.password,'email':obj.email}) # 顯示input,而且將數據庫中的默認值填寫到input框中 (編輯的時候用)
每一個表單字段都有一個對應的Widget
類,它對應一個HTML 表單Widget
,例如<input type="text">
。
在大部分狀況下,字段都具備一個合理的默認Widget。例如,默認狀況下,CharField
具備一個TextInput Widget
,它在HTML 中生成一個<input type="text">
。
無論表單提交的是什麼數據,一旦經過調用is_valid()
成功驗證(is_valid()
返回True
),驗證後的表單數據將位於form.cleaned_data
字典中。這些數據已經爲你轉換好爲Python 的類型。
注:此時,你依然能夠從request.POST
中直接訪問到未驗證的數據,可是訪問驗證後的數據更好一些。
在上面的聯繫表單示例中,is_married將是一個布爾值。相似地,IntegerField
和FloatField
字段分別將值轉換爲Python 的int
和float
。
3、數據庫表設計
設計表時注意的幾點:
一、 nid = models.AutoField(primary_key=True) #若是不指定django會默認加上id的
nid = models.BigAutoField(primary_key=True) #但那些整型知足不了你的時候,就用BigAutoField
二、對於類的註釋通常加在類裏面
三、verbose_name=「標題」 字段的中文提示
四、ForeignKey(to = "表名",tofield= "字段") #這兩個to能夠不用寫,可是關聯的表名必定要寫
五、releated_name = "uuu" 反向查詢。若是一個表中有多個ManyTwoMany()或者ForeignKey()必須加上releated_name
六、字段常常變更的適合連表
字段變化小,不怎麼變的適合在一個表中,不進行連表:就用choices
吧班主任和老師能夠放到一個表中、由於他們有相同的屬性,若是屬性全是同樣的,能夠放在一個表裏(推薦)
也能夠分開放,老師表是老師表,班主任表是班主任表。這樣就會進行連表操做,連表有性能消耗。
舉例:文章和文章類型
分析:一個文章有一個類型,一個類型能夠對應多個文章(因此文章和文章類型是一對多的關係,關聯字段要放在多的一方)
一:連表設計:
class News(models.Model): title = models.CharField(max_length=32) summary = models.CharField(max_length=255) news_type = models.ForeignKey(to="NewsType") class NewsType(models.Model): type_title = models.CharField(max_length=32) News: id title summary news_type_id t.... 科技... 2 t.... 科技... 1 t.... 科技... 2 NewsType: id title 圖片 挨踢1024 段子 # 查看全部新聞 new_list = models.News.objects.all() for row in new_list: print(row.title,row.summary,row.news_type.title)
二 :放在一個表中的操做:choices
class News2(models.Model): title = models.CharField(max_length=32) summary = models.CharField(max_length=255) news_type_chices = ( (1, '圖片'), (4, '挨踢1024'), (3, '段子'), ) news_type = models.IntegerField(choices=news_type_chices) # 查看全部新聞 new_list = News.objects.all() for row in new_list: print(row.title,row.summary, row.get_news_type_display() )
舉例二:用戶和用戶類型
一:連表設計
class UserType(models.Model): """ 用戶類型表,個數常常變更 """ title = models.CharField(max_length=32) class UserInfo(models.Model): """ 用戶表:講師和班主任 """ username = models.CharField(max_length=32) password = models.CharField(max_length=64) email = models.CharField(max_length=32) ut = models.ForeignKey(to="UserType")
二:不連表設計:choices
class UserInfo(models.Model): # """ # 用戶表 # """ username = models.CharField(max_length=32) password = models.CharField(max_length=64) email = models.CharField(max_length=32,verbose_name="郵箱") user_type_choices = ( (1, '班主任'), (2, '講師'), ) user_type_id = models.IntegerField(choices=user_type_choices)
4、登陸
可設置一個裝飾器
def auth(func): def inner(request,*args,**kwargs): is_login = request.session.get("is_login", None) if not is_login: return redirect("/login/") ret = func(*args,**kwargs) return ret return inner
須要注意的:
一、action不寫路徑,默認提交到當前
二、向後臺提交數據用post,獲取數據用get
三、submit通常加上value,有些瀏覽器可能會不識別
四、通常配置文件的鍵都是大寫的
5、Form基本使用
類 字段 is_valid() cleaned_data errors 字段參數: max_length min_length validators = [RegexValidators("XXX")] 鉤子函數: clean_字段名 注意: 必須有返回值 只能拿本身當前字段值 raise ValidationError("XXX") 下拉框數據源時時更新: 一、重寫init方法 先執行父類構造方法 self.fields["xx"].choices = XXXX 二、ModelChoiceField
用戶登陸
- form的字段能夠定義正則表達式 password = fields.CharField( required=True, min_length=3, max_length=18, error_messages={ 'required': '密碼不能爲空', 'min_length': '密碼長度不能小於3', 'max_length': '密碼長度不能大於18', 'invalid': '密碼格式錯誤', }, validators=[RegexValidator('\d+','只能是數字') ] ) 注意:error_messages的優先級比validators高
class LoginForm(Form): username = fields.CharField( required=True, #必填字段 min_length=3, max_length=16, error_messages={ "required":"用戶名不能爲空", "min_length":"長度不能小於3", "max_length":"長度不能大於16" }, widget=widgets.TextInput({"placeholder":"username","class":"form-control"}) ) password = fields.CharField( required=True, min_length=3, max_length=16, error_messages={ "required": "密碼不能爲空", "min_length": "密碼長度不能小於3", "max_length": "密碼長度不能大於16", # "invalid":"密碼格式錯誤" # error_messages的優先級高,若是寫上"invalid":"密碼格式錯誤"這個就會優先顯示這個錯誤 }, widget=widgets.PasswordInput({"placeholder":"password","class":"form-control"}), validators=[RegexValidator("\d+","密碼只能是數字")] #能夠進行正則匹配提示錯誤 ) def clean_username(self): user = self.cleaned_data["username"] is_exits = models.UserInfo.objects.filter(username=user).count() if not is_exits: raise ValidationError("用戶名和密碼錯誤") return user #必須有return
- 主動向form中添加錯誤信息
# form.add_error('password','用戶名或密碼錯誤')
form.add_error('password',ValidationError('用戶名或密碼錯誤'))
這兩個均可以,建議用第二個
Form擴展(鉤子函數)
若是對username作擴展
#先作正則表達式判斷
#而後自定義方法驗證:也就是clean_xx,稱爲鉤子函數
def clean_username(self): #能夠寫本身的驗證提示 不像validators只寫正則表達式。在這裏能夠隨意寫 user=self.clean_data["username"] is_esits = models.UserInfo.objects.filter(username=user).count() if not is_esits: raise validationError("用戶名不存在") return user #必須有返回值 若是 def clean_username(self): 只能取password字段的值 若是 def clean_username(self): 只能取username字段的值 注意:在本身寫鉤子函數的時候,只能拿本身的字段不能拿別人的 每一種字段就能夠用 正則+自定義正則+自定義鉤子函數