软件:Pycharm2020
Python:python3.7.5
Django:django3.0.8
数据库:mysql5.7.30
github链接 https://github.com/yt-xy/Django-student
用类的好处就是我们可以分离GET和POST的处理逻辑,把之前index函数中单一的流程变成结构化的处理流程。
url.py
from stu.views import index, IndexView
urlpatterns = [
url(r'^admin/', admin.site.urls),
# url(r'^$', index, name='index'),
url(r'^$', IndexView.as_view(), name='index'),
]
view.py
class IndexView(View):
template_name = 'index.html'
def get_context(self):
students = Student.get_all()
context = {
'students': students,
}
return context
def get(self, request):
context = self.get_context()
form = StudentForm()
context.update({
'form': form
})
return render(request, self.template_name, context=context)
def post(self,request):
form = StudentForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('index'))
context = self.get_context()
context.update({
'form': form
})
return render(request, self.template_name, context=context)
中间件
process_request:这是请求来到middleware中时进入的第一个方法。一般情况下,我们可以在这里做一些校验,比如用户登录或者HTTP中是否有认证头之类的验证。这个方法可以有两种返回值-HttpResponse或者None。如果返回的HttpResponse,那么接下来的处理方法只会执行process_response,其他方法不会被执行。这里需要注意的是,如果你的middleware是settings配置的MIDDLEWARE的第一个,那么剩下的middleware也不会被执行;如果返回None,那么Django会继续执行其他方法。
process_view:这个方法是在process_request方法之后执行的,参数如上面代码所示,其中func就是我们要执行的view方法。因此,如果要统计一个view的执行时间,可以在这里做。它的返回值跟process_request一样,是HttpResponse或者None,其逻辑也一样,如果返回None,那么Django会帮你执行view函数,从而得到最终的resquest。
process_template_response:执行完上面的方法,并且Django帮我们执行完view,拿到最终的response后,如果使用了模板的response(这是值通过return render(request, ‘index’, context{})方式返回的response),就会来到这个方法中。在这个方法中,我可以对response做一下操作,比如Content-Type设置,或者其他header的修改/增加。
process_response:当所有流程都处理完毕后,就来到了这个方法。这个方法的逻辑跟process_template_response是完全一样的,只是后者针对的带有模板的response的处理。
process_exception:上面的处理方法是按顺序介绍的,而这个方法不太一样。只有在发生异常时,才会进入这个方法。哪个阶段会发生异常呢?可以简单理解为在将要调用的View中出现异常(就是在process_view的func函数中)或者返回的模板response在渲染时发生的异常。但是需要注意的是,如果你在process_view中手动调用了func,就像我们上面做的那样,就不会触发process_exception了。这个方法接收到异常之后,可以选择处理异常,然后返回一个含有异常信息的HttpResponse,或者直接返回None不处理,这种情况下Django会使用自己的异常模板。
统计首页每次访问程序所消耗的时间–统计Django生成request之后返回response之前的信息
middleware.py
import time
from django.urls import reverse
from django.utils.deprecation import MiddlewareMixin
class TimeItMiddleware(MiddlewareMixin):
def process_request(self, request):
return
def process_view(self, request, func, *args, **kwargs):
if request.path != reverse('index'):
return None
start = time.time()
response = func(request)
costed = time.time() - start
print('process view: {:.2f}s'.format(costed))
return response
def process_exception(self, request, exception):
pass
def process_template_response(self, request, response):
return response
def process_response(self, request, response):
return response
修改后
import time
from django.urls import reverse
from django.utils.deprecation import MiddlewareMixin
class TimeItMiddleware(MiddlewareMixin):
def process_request(self, request):
self.start_time = time.time()
return
def process_view(self, request, func, *args, **kwargs):
if request.path != reverse('index'):
return None
start = time.time()
response = func(request)
costed = time.time() - start
print('process view: {:.2f}s'.format(costed))
return response
def process_exception(self, request, exception):
pass
def process_template_response(self, request, response):
return response
def process_response(self, request, response):
costed = time.time() - self.start_time
print('request to response cose: {:.2f}s'.format(costed))
return response
settings.py
MIDDLEWARE = [
'stu.middleware.TimeItMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# 放在第一行一定要记得加','!