Django 接收到浏览器的发送的请求之后, 进行 URL 匹配,找到对应的视图进行响应。
FBV
和 CBV
FBV(function base views)使用视图函数处理请求
CBV(class base views) 使用视图类处理请求
views.py:
from django.http import HttpResponse
from django.views import View
# path('login/', views.login),
def login(request):
return HttpResponse("login")
# path('user/', views.UserView.as_view()),
class UserView(View):
def get(self, request):
return HttpResponse("GET")
def post(self, request):
return HttpResponse("POST")
request
:
print(type(request)) # <class 'django.core.handlers.wsgi.WSGIRequest'>
from django.core.handlers.wsgi import WSGIRequest
# 点击 WSGIRequest 即可查看参数
# 补充:
# WSGIRequest 中装饰器 @property 的作用:可以不用加括号
# 如:request.GET() -> request.GET
# @cached_property 会添加一个缓存,访问同一个参数时减少解析次数
# QueryDict: 特殊的字典,key 可以重复
# POST = property(_get_post, _set_post) 中 property 的作用:
# p = obj.POST 就执行 _get_post,obj.POST = 123 就执行 _set_post
# 常用的参数有:
request.method
request.GET
request.POST
request.FILES
request.path_info
request.body
request.resolver_match
request.session
# HttpResponse -> 构建响应体和响应头
HttpResponse("login")
# class JsonResponse(HttpResponse): # ...
JsonResponse({"status": True, "return": "login"})
# xxx.txt: "login"
render(request, "xxx.txt")
render(request, "xxx.html")
# 重定向
# 永久重定向:permanent=True,状态码:301,多用于旧网址被废弃了要转到一个新的网址
# 临时重定向(默认):permanent=False,状态码:302,比如用户没有登陆要跳转到登录页面
# 响应头里面放一个 Location ,浏览器读取到之后会像 Location 指向的网址再次发送请求
redirect("http://xx.com")
# login/ --> views.login
path('login/', views.login),
# user/ --> as_view()方法的返回值
path('user/', views.UserView.as_view()),
UserView.as_view() -> View.as_view():
返回 view
函数,如果是 GET
请求,则返回的就是 UserView.get()
# path('user/', views.UserView.as_view()), GET 请求
def dispatch(self, request, *args, **kwargs):
# 尝试分派到正确的请求方法
if request.method.lower() in self.http_method_names:
# handler = self.request.method.lower() => UserView.get()
handler = getattr(
self, request.method.lower(), self.http_method_not_allowed
)
else:
# 请求不存在或者请求不在批准的列表里面
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs) # UserView.get()
def as_view(cls, **initkwargs):
"""Django 处理 HTTP 请求的入口"""
# cls: <class 'app.views.UserView'>
# cls.http_method_names = ["get","post","put","patch","delete","head","options","trace",]
# cls.view_is_async = False
# initkwargs: {}
for key in initkwargs:
# 用户传入 HTTP 方法名相同的参数时,会报错。目的是避免意外覆盖类视图的 HTTP 请求处理方法
# 如:as_view(get='some_value') 会发生报错
if key in cls.http_method_names:
raise # ......
if not hasattr(cls, key):
raise # ......
# 闭包
def view(request, *args, **kwargs):
# 实例化 UserView 对象
# self = UserView()
self = cls(**initkwargs)
# 初始化各个参数
# self.request = request ...
self.setup(request, *args, **kwargs)
if not hasattr(self, "request"):
raise # ......
# 返回 self.dispatch -> UserView.get()
return self.dispatch(request, *args, **kwargs)
view.view_class = cls # <class 'app.views.UserView'>
view.view_initkwargs = initkwargs # {}
# ......
return view