Django(二)、Http请求处理

前言
最常见的http请求method,是get和post方式,除此之外还有head\option\delete\put\patch等方式。默认输入url的请求方式即为get,当请求方式为get时,若带有需要传递的其他参数,则会将该参数的name和value补充在url中一并提交,post方式则将数据放在内容中一并提交,不再url中显示。在浏览器发送的request数据包的header中,可以看到这些内容,例如:
这里写图片描述

那么在django中,是如何获取这些请求的方式和如何定义处理这些请求的呢?现在来分析上一节( Django(一)、基本使用)的内容。

一、FBV方式处理请求
模板页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/login_test/" method="post">
        <input type="text" name="info" placeholder="info">
        <input type="submit">
    </form>
    <p><h2>INFO:{{ info }}</h2></p>
    <p><h2>Method:{{ method }}</h2></p>
</body>
</html>
def login_test(request):
    info=""
    if request.method=='POST':
        info=request.POST.get('info')
    return render(request,"login_test.html",{'info':info,'method':request.method})

客户端的请求,作为实参传递给形参request,request.method可以获取该请求header中的method方式,reques.POST.get(‘info’)可以获取客户端通过POST方式传递过来的name为info的key对应的value。

在urls.py中绑定该函数

url(r'^index_test/', enginetest_views.index_test),

打开http://127.0.0.1:8000//login_test/
默认如下:
这里写图片描述
输入任意值点击提交后如下:
这里写图片描述

TIPS:当前端为复选框,向后端Django传递的值有多个时,可以通过request.POST[GET].getlist(‘KEY’)的方式,获取值的数组,格式为[VALUE1,VALUE2..]

以上使用的是函数绑定url,即FBV(function base view)方式处理请求,url绑定放在views.py文件中的函数,绑定的写法为:路径→函数,url(r’^login/’, common_view.login)
同时,django支持CBV(class base view)方式处理请求。

二、CBV的方式处理请求
views.py中的类写法:

from django.views import View  #引入django View父类
# Create your views here.
class Login_test(View):
    def get(self,request):
        info=""
        return render(request,"login_test.html",{'info':info,'method':request.method})

    def post(self,request):
        info=request.POST.get('info')
        return render(request,"login_test.html",{'info':info,'method':request.method})

# def login_test(request):
#     info=""
#     if request.method=='POST':
#         info=request.POST.get('info')
#     return render(request,"login_test.html",{'info':info,'method':request.method})

urls.py绑定写法:

# url(r'^login_test/', enginetest_views.login_test),
url(r'login_test/',enginetest_views.Login_test.as_view()) //将上方注释,替换为此句

实现效果和上方FBV一致。
原理介绍:

'''
以上FBV方式,function base view,url绑定放在views.py文件中的函数,绑定的写法为:路径→函数,url(r'^login/', common_view.login),
CBV方式,class base view,自定义个类,继承django.view中的View父类,绑定写法为:路径→类,url(r'^login/', common_view.Test.as_view()),
使用FBV的方式,各请求方法对应的逻辑需要自己判断编写,使用CBV的方式,由django中的View类中的dispatch方法来判断请求method,并交给对应method的函数来处理请求。
使用CBV时,可以自定义一些操作,例如在接收到请求处理之前,和请求处理完毕答复之前,都可以进行一些操作。
'''
'''
#dispatch是django处理请求时优先执行的函数,该函数接收并分析请求头部中的方法字段,根据请求中的方法,使用getattr,将请求交给相应的函数去处理。
参考View.dispatch源码:
    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)
'''

使用CBV,可以自定义或插入添加一些功能,例如简单修改View.dispatch方法,在接收到请求和回应请求之后分别输出打印:

class Login_test(View):
    def dispatch(self, request, *args, **kwargs):
        print('****,recv request')
        res=super(Login_test,self).dispatch(request, *args, **kwargs)  #继承父类的方法处理请求,res接收父类方法return值。
        print('****,return request')
        return res
    def get(self,request):
        info=""
        return render(request,"login_test.html",{'info':info,'method':request.method})

    def post(self,request):
        info=request.POST.get('info')
        print(info)
        return render(request,"login_test.html",{'info':info,'method':request.method})

在客户端访问http://127.0.0.1:8000/login_test/时,查看console的输出,可以看到记录:

****,recv request
****,return request
[15/Jan/2018 15:00:45] "GET /login_test/ HTTP/1.1" 200 327

总结:
FBV和CBV两种方式没有孰优孰劣,只是CBV方式有着更高的自定义性,可以实现更多的功能。

猜你喜欢

转载自blog.csdn.net/ywq935/article/details/79064690
今日推荐