django的视图主要有两种,分别是函数视图和类视图,也就是FBV和CBV,先学习FBV
1.请求方式
常见的请求方式如下
GET:获取数据
POST:添加数据
DELETE:删除数据
PUT:更新数据
PATCH 局部更新
...
求方式本质上没什么不同,只是认为的区分不同的请求做不同的事情
2.请求对象
GET /search HTTP/1.1 # 请求首行包含请求方式 请求路径和协议版本 # 请求头由键值对组成 application/msword, application/x-silverlight, application/x-shockwave-flash, */* Referer: <a href="http://www.google.cn/">http://www.google.cn/</a> Accept-Language: zh-cn 请求体 。。。
那么在django中如何获取各个部分的数据呢?
2.1 获取请求方法
request.method
2.2 获取请求数据
request.GET # 获取所有的GET请求 request.GET.get("name") # 获取GET中指定键的数据 request.GET.getlist("name") # 获取GET中指定的数据列表
from django.shortcuts import render, HttpResponse, redirect def index(request, nid): print(request.GET) # <QueryDict: {'name': ['kunmzhao', 'wuqiaozhen'], 'age': ['27']}> print(request.GET.get('name')) # wuqiaozhen print(request.GET.getlist('name')) # ['kunmzhao', 'wuqiaozhen'] return HttpResponse('OK')
- 获取post请求方式的数据
post请求的数据会存放在请求体中
方式一:
request.POST # 获取所有的POST请求 request.POST.get("name") # 获取POST指定键的数据 request.POST.getlist("name") # 获取POST中指定的数据列表
方式二
# 存放的是请求体的原始数据 request.body
2.3 获取请求路径
request.path # 不包含get请求的参数 get_full_path() # 包含get请求的参数
print(request.path) # /app01/index/1 print(request.get_full_path()) # /app01/index/1?name=kunmzhao
2.4 获取请求头
request.headers # 包含请求头的所有信息
{ 'Content-Length': '280', 'Content-Type': 'multipart/form-data; boundary=--------------------------231440296425196999483632', 'User-Agent': 'PostmanRuntime/7.29.0', 'Accept': '*/*', 'Postman-Token': '835fbdd7-2ba9-43a3-abec-ba66725b3fef', 'Host': '127.0.0.1:9000', 'Accept-Encoding': 'gzip, deflate, br', 'Connection': 'keep-alive' }
3.响应对象
-
HttpResponse()
-
JsonResponse()
-
render()
-
redirect()
后面三种都是直接或者间接的继承了HttpResponse
3.1
常用的属性
content:响应内容 status:响应状态码,默认为200 content_type:返回数据的类型。默认为text/html,也可以指定为text/plain的纯文本,或者application/json的json格式数据 设置响应头 response['name'] = "kunmzhao"
def index(request, nid): response = HttpResponse(content='OK', status=200, content_type='text/plain') response['name'] = 'kunmzhao' return response
content:响应内容 status:响应状态码,默认为200 content_type:返回数据的类型。默认为text/html,也可以指定为text/plain的纯文本,或者application/json的json格式数据 设置响应头 response['name'] = "kunmzhao"
from django.http import JsonResponse def index(request): return JsonResponse({"title":"三国演义","price":199})
常用属性
request: 客户端请求 template_name:模板名称 context=None:上下文,用于渲染模板文件的数据 status:状态码
视图
def index(request, nid): return render(request, 'index.html', {'nid':nid})
模板
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <p><a href="{% url "app01:index" nid %}">hello</a></p> </body> </html>
该方法是重定向,
# return redirect("https://www.baidu.com/") # 完整url
return redirect(reverse("app01:index", kwargs={"nid": nid})) # 反向生成
4.CBV
类需要继承django中的View,然后指定get, post等方法,在路由中设定BookView.as_view(),当get请求到来会自动指定get方法
路由
from django.contrib import admin
from django.urls import path, include
from apps.app01.views import BookView
urlpatterns = [
path('admin/', admin.site.urls),
path('book/', BookView.as_view())
]
视图
from django.shortcuts import render, HttpResponse from django.views import View class BookView(View): def get(self, request): return HttpResponse('这是一个get请求') def post(self, request): return HttpResponse('这是一个post请求') def delete(self, request): return HttpResponse('这是一个delete请求')
源码解析
as_view函数返回的是view函数,当路到达的时候,就会执行该函数,返回dispatch函数的执行结果,dispatch则通过反射寻找类中对应请求方法的函数,然后执行
def as_view(cls, **initkwargs): ... def view(request, *args, **kwargs): self = cls(**initkwargs) self.setup(request, *args, **kwargs) if not hasattr(self, 'request'): raise AttributeError( "%s instance has no 'request' attribute. Did you override " "setup() and forget to call super()?" % cls.__name__ ) return self.dispatch(request, *args, **kwargs) view.view_class = cls view.view_initkwargs = initkwargs # take name and docstring from class update_wrapper(view, cls, updated=()) # and possible attributes set by decorators # like csrf_exempt from dispatch update_wrapper(view, cls.dispatch, assigned=()) return view
def dispatch(self, request, *args, **kwargs): # Try to dispatch to the right method; if a method doesn't exist, # defer to the error handler. Also defer to the error handler if the # request method isn't on the approved list. if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs)