Python Web 框架-Django day06
阿新 • • 發佈:2018-12-16
目錄
day05
1.F 和 Q
- F() Author.objects.all().update(age=F('age')+10)
- Q() Q()|Q() Author.objects.filter(Q(id=1)|Q(age_gte=35))
2.原生方法
- 查詢 - raw() Entry.objects.raw(sql)
- 增刪改 with connection.cursor() as cursor: cursor.execute(sql)
3.使用後臺管理Models
- 基本管理
- def __str__(self):
- 內部類 - Meta
- db_table
- verbose_name
- verbose_name_plural
- ordering = []
- verbose_name name = model.CharField(max_length='',verbose_name)
- 高階管理
- 高階管理類 繼承自admin.ModelAdmin 註冊高階管理類 admin.site.register(Entry,EntryAdmin)
- 高階管理屬性
- list_display
- list_display_links
- list_editable
- search_fields
- list_filter
- date_hierarchy
- fields
- fieldsets fieldsets = ( #分組1 ('分組名稱',{ 'fields':('屬性1','屬性2'), 'classes':('collapse',), }), #分組2 ()
4.關係對映
- 一對一
- 設定一對一 任何一個實體中: 屬性 = models.OneToOneField(Entry)
- 反向引用 屬性:對應的實體類名全小寫
- 一對多
- 多的實體中增加對一的引用 屬性=models.ForeignKey(Entry)
- 反向引用 屬性:類名全小寫_set
- 多對多
- 設定多對多 任何一個類中 屬性 = models.MantToManyField(Entry
- 反向引用 屬性:類名全小寫_set
1.Django ORM
- 自定義查詢物件 - objects
Entry.objects.filter()
- 宣告類 EntryManager 繼承自 models.Manager 允許在 EntryManager 中新增自定義函式 class EntryManager(models.Manager): def 函式名(self,自定義引數列表): ... ... return ... ...
- 使用 EntryManager 覆蓋 Models類中原有的objects class Entry(models.Model): objects = EntryManager() name = models.CharField(xxx) 練習: 為Author 實體自定義objects物件,增加一個函式,用於查詢年齡小於指定年齡值的作者的QuerySet
2.HttpRequest - 請求
- 什麼是HttpRequest HttpRequest,在Django中就是請求物件的封裝體現,裡面封裝了請求過程中的所有資訊,在Django中HTTPRequest被封裝成了request物件,被封裝到請求處理檢視函式中做為引數,在呼叫檢視時自動傳入
- HTTPRequest中的主要內容
- request.scheme :請求協議
- request.body:請求主體
- request.path:請求路徑(具體資源路徑)
- request.get_host():請求的主機地址 / 域名
- request.method:獲取請求方法
- request.GET:封裝了get請求方式所提交的資料
- request.POST:封裝了post請求方式所提交的資料
- request.COOKIES:封裝了cookies 中所有資料
- requestMETA:封裝了請求的元資料 request.META.HTTP_REFERER:封裝了請求的源地址
- 獲取請求提交的資料
- get請求方式
request.GET['名稱']
request.GET.get['名稱']
- 使用表單提交資料 <form method='get'></form>
- 通過地址拼查詢字串 <a href="地址?引數1=值1&引數2=值2"></a> DJango 中通過 url 傳參 url(r'^xxx/(\d+)') 該寫法屬於Django表準,並非Http標準,不能用request.GET[]
- post請求方式
request.POST['名稱']
CSRF:Crose-Site Request Forgery
跨站點 請求 偽裝
解決方案:
- 如果想通過 CSRF驗證,則需要在表單中的第一行增加 {% csrf_token %}
- 取消 csrf 的驗證 刪除 settings.py 中 MIDDLEWARE 中 CsrfViewMiddleware 中介軟體
- 在處理函式上增加裝飾器
@csrf_protect
@csrf_protect
def post_views(request):
xxx
練習:完成果園註冊操作
- 建立資料庫 - fruit
- 建立實體類 - User uphone - 手機號 upwd - 密碼 uname - 使用者名稱 uemail - 電子郵件 isActive - 是否啟用
- 完善註冊模板,提交資料庫時,將資料儲存進資料庫
- get請求方式
request.GET['名稱']
request.GET.get['名稱']
3.使用forms模組處理表單
- forms模組的作用 通過forms模組,允許將表單與class相結合,允許通過class生成表單
- 使用 forms 模組
- 建立forms.py檔案
- 匯入 django 的 forms from dhango import forms
- 建立 class,一個class 對應生成一個表單 class ClassName(forms.Form) pass
- 在 class 中建立屬性
一個屬性對應到表單中會生成一個控制元件
forms.py
from django import forms # 為topic控制元件初始化資料 TOPIC_CHOICE = ( ('1','好評'), ('2','中評'), ('3','差評'), ) #表示評論內容的表單控制元件們 #控制元件1 - 評論標題 - 文字框 #控制元件2 - Email - Email框 #控制元件3 - 評論內容 - Textarea #控制元件4 - 評論級別 - Select #控制元件5 - 是否儲存 - Checkbox class RemarkForm(forms.Form): # subject - input type='text' # label 表示的是控制元件前的文字 subject=forms.CharField(label='標題') # email - input type='email' email = forms.EmailField(label='郵箱') # message - Textarea # widget=forms.Textarea,表示將當前屬性變為多行文字域 message = forms.CharField(label='內容',widget=forms.Textarea) # topic - Select topic = forms.ChoiceField(label='級別',choices=TOPIC_CHOICE) # isSaved - checkbox isSaved = forms.BooleanField(label='是否儲存')
- 在模板中解析 form 物件
- 注意
- 需要自定義 <form>
- 需要自定義按鈕
- 處理方法
在檢視中建立 form 的物件,併發送到模板中
ex:
form = RemarkForm()
return render(request,'xxx.html',locals())
index應用下的views.py
在模板中解析 form 物件def form_views(request): if request.method == 'GET': form = RemarkForm() return render(request,'04-form.html',locals()) else: # subject = request.POST['subject'] # email = request.POST['email'] # message = request.POST['message'] # topic = request.POST['topic'] # isSaved = request.POST['isSaved'] # print(subject,email,message,topic,isSaved) # 通過RemarkForm自動接收資料 # 1.將request.POST資料傳遞給RemarkForm構造器 form = RemarkForm(request.POST) # 2.驗證form物件 if form.is_valid(): # 3.通過驗證後獲取具體的資料 cd = form.cleaned_data subject = cd['subject'] email = cd['email'] isSaved = cd['isSaved'] message = cd['message'] topic = cd['topic'] print(subject,email,isSaved,message,topic) return HttpResponse('Post OK')
- 手動解析 在模板中 {% for field in form %} {{field}} 表示的就是控制元件 {{field.label}}表示的是控制元件中label的值 {% endfor %}
- 自動解析
- {{form.as_p}} 將form物件中的每個屬性使用p標記包裹起來,再顯示
- {{form.as_ul}} 將form物件中的每個屬性使用li標記包裹起來,再顯示在網頁上 注意:必須手動提供<ol></ol> 或 <ul></ul>
- {{form.as_table}}
將form物件中的每個屬性使用tr標記包裹起來,再顯示在網頁上,
注意:必須手動提供 <table>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> /*#id_subject{ border:2px solid #f00; }*/ input[name='subject']{ border:2px solid #ff0; border-radius:3px; } </style> </head> <body> <form action="/04-form/" method="post"> {% csrf_token %} {% comment '手動解析' %} {% for field in form %} <p> {{ field.label }}:{{ field }} </p> {% endfor %} {% endcomment %} <ul> {{ form.as_ul }} </ul> <p> <input type="submit" value="提交"> </p> </form> </body> </html>
- 注意
- 在檢視中,通過 forms.Form 自動獲取表單資料
- 通過 forms.Form 的構造器來接收post資料 form = XXXForm(request.POST)
- 必須使form通過驗證之後,再取值 form.is_valid() 返回True:提交的資料已通過所有驗證,允許取值(返回的是一個字典) 返回False:提交的資料未通過驗證,無法取值
- 獲取表單中資料 通過 form.cleaned_data 來接收提交的資料
未完待續