django的视图主要有两种,分别是函数视图和类视图,也就是FBV和CBV,先学习FBV

1.请求方式

常见的请求方式如下

GET:获取数据
POST:添加数据
DELETE:删除数据
PUT:更新数据
PATCH 局部更新
...

求方式本质上没什么不同,只是认为的区分不同的请求做不同的事情

2.请求对象

django会将客户端的请求全部封装在request参数中,一般是只读的

请求一般分为:请求首行 请求头和请求体

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 获取请求数据

  • 获取get请求方式的数据
    get请求的数据会存放在请求首行的请求路径之后,通过?进行分割
    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.响应对象

在django中的响应对象主要有四种形式

  • HttpResponse()

  • JsonResponse()

  • render()

  • redirect()

后面三种都是直接或者间接的继承了HttpResponse

3.1 HttpResponse

HttpResponse是所有响应对象的基类,将响应给客户端的数据封装成HTTP协议

常用的属性

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

 

3.2 JsonResponse

可以将对象封装成json的对象,并且指定数据类型为application/json

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})

 

3.3 render

将一个模板文件渲染成一个html,响应给客户端,模板知识在后续总结

常用属性

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>

 

3.4 redirect

该方法是重定向,参数为一个固定的URL

# return redirect("https://www.baidu.com/")  # 完整url
return redirect(reverse("app01:index", kwargs={"nid": nid}))  # 反向生成

 

4.CBV

CBV的本质其实也是FBV

类需要继承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)

 

posted on 2022-11-16 14:39  阿明明  阅读(27)  评论(0编辑  收藏  举报