「django 學習」第 2 篇死遭,淺談類視圖、中間件
填坑
接上篇的學生管理系統(tǒng)凯旋,對于我們現在的需求來說呀潭。我們不必改寫為 Class-based View,這里只是演示用法至非。
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render
from django.urls import reverse
from django.http import HttpResponseRedirect
from django.views import View
from .models import Student
from .forms import StudentForm
class IndexView(View):
template_name = 'index.html'
def get_context(self):
students = Student.objects.all()
context = {
'students': students
}
return context
def get(self, request):
form = StudentForm()
context.update({
'form': form
})
return render(request, self.template_name, context)
def post(self, request):
form = StudentForm(request.POST)
if form.is_valid():
student = Student()
student.name = form.cleand_data['name']
student.sex = form.cleand_data['sex']
student.profession = form.cleand_data['profession']
student.email = form.cleand_data['email']
student.qq = form.cleand_data['qq']
student.save()
return HttpResponseRedirect(reverse('index'))
context.update({
'form': form
})
return render(request, self.template_name, context)
在代碼層面上钠署,代碼量明顯增多了,但是邏輯上更清晰了荒椭,也方便我們日后維護谐鼎。我們來改寫 urls.py
,代碼如下:
from django.conf.urls import url
from django.contrib import admin
from student import views
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^admin/', admin.site.urls),
]
只是調用了 as_view()
趣惠,可以簡單的理解為把 get
和 post
做了一層封裝狸棍,然后做了判斷。
使用 Class-based View 可以方便復用味悄,比如項目中草戈,你的邏輯處理都沒變,只不過用的模板不一樣侍瑟。那么直接繼承唐片,替換模板文件即可。更多的可以參考官方文檔: django官方文檔
Middleware
中間件是 Django 處理 請求/響應 的鉤子框架涨颜。它是一個輕巧的低級 “插件” 系統(tǒng)费韭,用于全局改變Django的輸入或輸出。
在這之前咐低,我們先來看張圖:
一個 HttpRequest 進來揽思,是從上往下,一層層過濾的见擦。返回 HttpResponse钉汗,是從下往上的。
其實跟 Scrapy
的中間件很相似鲤屡,不過一個是主動發(fā)起的 request损痰,比如 Scrapy
中,你想要在發(fā)出 request 的時候帶上一些必要的請求頭酒来,可以這么來寫:
import random
from .agents import agents
class UAMiddleware(object):
def process_request(self, request, spider):
agent = random.choice(agents)
request.headers["User-Agent"] = agent
如果把 Scrapy
中重寫中間件比作攻擊方卢未,那么在 Django 中就好比防守方。下面來看 Stack overflow 的一個例子:
class FilterIPMiddleware(object):
# Check if client IP is allowed
def process_request(self, request):
allowed_ips = ['192.168.1.1', '123.123.123.123', etc...] # 允許的 IP
ip = request.META.get('REMOTE_ADDR')
if ip not in allowed_ips:
raise Http403 # If user is not allowed raise Error 如果用戶不再允許的范圍內,拋出 Error
return None
process_request
:一個請求來到 middleware 層辽社,進入的第一個方法伟墙。一般我們可以做一些檢驗,比如用戶登錄滴铅,Http 請求頭驗證之類的戳葵。這個方法返回兩個值 HttpResponse 或者 None。
關于中間件的其他幾個方法汉匙,比如 process_response
拱烁、process_exception
、process_view
噩翠、process_template_response
戏自,并沒有仔細的去研究,就不多說了伤锚,大家可以自行查看官方文檔擅笔。