Django 【第十一篇】Form組件基礎
一、model常用操作
1、13個API查詢:all,filter,get ,values,values_list,distinct,order_by ,reverse , exclude(排除),count,first,last,esits(判斷是否存在)
需要掌握的all、values、values_list的區別
all:打印的是一個QuerySet集合,一個列表裏面放的對象
values :是一個字典形式
values_list:是一個元組形式
all的性能是最低的
2、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裏面的字段,取其他的字段效率太低了,盡可能的少的連接數據庫
3、路由系統
反向生成URL:
有兩種方式:{% url "a1" %}
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})
4、Django的生命周期
Web服務器網關接口(Python Web Server Gateway Interface,縮寫為WSGI)
1、首先走wsgi模塊,這個模塊也是一個協議,包括wsgiref和uwsgi。
2、然後路由分配-------views視圖
3、從數據庫取數據-----------渲染到html
註意如果導入js文件,是不會渲染的。
5、HTTP協議
詳見下一篇博客
二、Form組件
一、Form組件介紹
Form組件可以做的幾件事情:
1、用戶請求數據驗證
2、自動生成錯誤信息
3、打包用戶提交的正確信息
4、如果其中有一個錯誤了,其他的正確這,保留上次輸入的內容
4、自動創建input標簽並可以設置樣式
二、Form組件的使用
1、創建規則
class Foo(Form): #必須繼承 username = xxx password = xxx email = xxx 註意這裏的字段必須和input的name字段一致
2、數據和規則進行匹配
先導入view.py
from django.forms import Form from django.forms import fields from django.forms import widgets
from django.shortcuts import render,redirect from app01 import models # Create your views here. from django.forms import Form from django.forms import fields from django.forms import widgets # 1、創建規則 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={"required":"郵箱不能為空!!","invalid":"無效的郵箱"}, widget=widgets.EmailInput(attrs={"placeholder": "郵箱", "class": "form-control"}) # 自動生成input框 ) #不能為空且郵箱格式要一致 # 2、使用規則:將數據和規則進行匹配 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) # print(form) #<QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]> if form.is_valid():# 開始驗證 # print(‘執行成功‘,form.cleaned_data) # 所有匹配成功,字典 # {‘username‘: ‘asd‘, ‘password‘: ‘sdf‘, ‘email‘: ‘[email protected]‘,‘ut_id‘:1} form.cleaned_data[‘ut_id‘] = 1 #要分的清是班主任還是講師 models.UserInfo.objects.all().create(**form.cleaned_data) return redirect("/teacherindex/") else: # print("=====?",form.errors,type(form.errors))#返回失敗的結果 # print(form.errors["username"][0]) #拿到返回失敗的結果,渲染到頁面 return render(request,"add.html",{"form":form})
html.py
{% block right %} <h1>添加老師信息</h1> <hr> <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> {% endblock %}
如果訪問視圖的是一個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框中 (編輯的時候用)
Widgets
每個表單字段都有一個對應的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
。
三、數據庫表設計
設計表時註意的幾點:
1、 nid = models.AutoField(primary_key=True) #如果不指定django會默認加上id的
nid = models.BigAutoField(primary_key=True) #但那些整型滿足不了你的時候,就用BigAutoField
2、對於類的註釋一般加在類裏面
3、verbose_name=“標題” 字段的中文提示
4、ForeignKey(to = "表名",tofield= "字段") #這兩個to可以不用寫,但是關聯的表名一定要寫
5、releated_name = "uuu" 反向查詢。如果一個表中有多個ManyTwoMany()或者ForeignKey()必須加上releated_name
6、字段經常變動的適合連表
字段變化小,不怎麽變的適合在一個表中,不進行連表:就用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
1 t.... 科技... 2
2 t.... 科技... 1
3 t.... 科技... 2
NewsType:
id title
1 圖片
2 挨踢1024
3 段子
# 查看所有新聞
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)
四、登錄
可設置一個裝飾器
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
需要註意的:
1、action不寫路徑,默認提交到當前
2、向後臺提交數據用post,獲取數據用get
3、submit一般加上value,有些瀏覽器可能會不識別
4、一般配置文件的鍵都是大寫的
Django 【第十一篇】Form組件基礎