django acquaintance 1

django

django acquaintance

Django essence of communication is based on socket

一。127.0.0.1 本地回环地址 后面:8001是端口号 /ppt是根目录下的ppt子网页
二。/当前网站的客户端(根目录)
例如:
127.0.0.1/#默认80可以不写

Functionality of a web frame;

1.使用socket收发信息
2.根据不同路径返回不同的内容
3. 返回动态的数据(字符串的替换 模板的渲染)

1569286224080

Several open-source version of the web framework

low version of the web framework

import socket
server=socket.socket()

server.bind(('127.0.0.1',8001))
server.listen()

while 1:
    conn,addr=server.accept()

    from_brower_msg=conn.recv(1024)
    path=from_brower_msg.decode('utf-8').split(' ')[1]#对收到消息编码转换成字符串,切割成列表【0】是方法【1】是对应的页面
#GET / HTTP/1.1
    #/是本页面的主页面 /后面的home page什么的都是对应的子页面
    print(path)
    conn.send(b'http/1.1 200 ok\r\n\r\n')
    if path=='/':#读取文件都用rb
        with open("04test.html",'rb')as f:
            data=f.read()
    elif path=='/style.css':#判断路径是否存在
        with open('style.css','rb')as f:
            data=f.read()
    elif path == '/mi.png':#每遇到一个url都会请求一次
        with open('mi.png', 'rb') as f:
            data = f.read()
    elif path=="./test.js":
        with open("test.js","rb")as f:
            data=f.read()
    conn.send(data)
    conn.close()

html page

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="./style.css"><!--从上往下执行 遇到io(地址主动向服务端发送请求)-->
</head>
<body>
<h2>24期官网</h2>
<div>
    <img src="./mi.png" alt=""><!--从上往下执行 遇到io(地址主动向服务端发送请求)-->
</div>
<script src="test.js"></script><!--从上往下执行 遇到io(地址主动向服务端发送请求)-->
</body>

</html>

Html file will be a problem as long jump

Upgraded version of multi-thread function

import socket
from concurrent.futures import ThreadPoolExecutor

server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(("127.0.0.1",8848))
server.listen()

#一定记得关闭连接 等待下一个连接请求
#处理页面请求的函数
def home(conn):
    with open('04test.html','rb')as f:
        data=f.read()
        conn.send(data)
        conn.close()#关闭连接等待下一个请求
#处理页面link( <link rel="stylesheet" href="test.css">)标签href属性值是本地路径的时候的请求        
def css(conn):
    with open('style.css','rb')as f:
        data=f.read()
        conn.send(data)
        conn.close()#关闭连接
#处理页面script(<script src="test.js"></script>)标签src属性值是本地路径的时候的请求
def js(conn):
    with open("test.js","rb")as f:
        data=f.read()
        conn.send(data)
        conn.close()

#处理页面img标签src属性值是本地路径的时候的请求

def pic(conn):
    with open("mi.png","rb")as f:
        data=f.read()
        conn.send(data)
        conn.close()#关闭
while 1:
    conn,addr=server.accept()
    from_brower_msg = conn.recv(1024)
    # print(from_brower_msg)
    path = from_brower_msg.decode('utf-8').split(' ')[1]
    print(path)
    conn.send(b'HTTP/1.1 200 ok\r\n\r\n')
    urlpatterns = [
        ('/',home),
    ('/style.css',css),
    ('/test.js',js),
    ('/mi.png',pic)
    ]
    #线程池
    for url in urlpatterns:
        if path ==url[0]:
            # ret=url)[1](
            t=ThreadPoolExecutor()#开启一个线程池
            t.submit(url[1],conn)#
            break
      else:
        conn.send(b'404')
 ············································       #多线程
    for url in urlpatterns:
        if path == url[0]:
           t = Thread(target=url[1],args=(conn,))
            t.start()
            break
    else:
        conn.send(b'404')

jinja2 third-party framework and built wsgiref similar socketserver

jinja2 (browser rendering) is essentially a string replacement

Query the database to replace the contents of the text, reading r

Replace replace string

With jinja2 unique rendering method flask stuff inside is not rendered using the rendering jinja2

wsgiref sum jinja

from wsgiref.simple_server import make_server
from jinja2 import Template


def index():
   # 把数据库中查询到的内容进行文本的替换,读取用r 
    with open("index2.html", "r",encoding='utf-8') as f:
        data = f.read()
    template = Template(data)  # 生成模板文件
    ret = template.render({"name": "于谦", "hobby_list": ["烫头", "泡吧"]})  # 把数据填充到模板里面
    return [bytes(ret, encoding="utf8"), ]


# 定义一个url和函数的对应关系
URL_LIST = [
    ("/index/", index),
]
#environ返回的是一个字典
def run_server(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ])  # 设置HTTP响应的状态码和头信息
    url = environ['PATH_INFO']  # 取到用户输入的url
    func = None  # 将要执行的函数
    for i in URL_LIST:
        if i[0] == url:
            func = i[1]  # 去之前定义好的url列表里找url应该执行的函数
            break
    if func:  # 如果能找到要执行的函数
        return func()  # 返回函数的执行结果
    else:
        return [bytes("404没有该页面", encoding="utf8"), ]


if __name__ == '__main__':
    httpd = make_server('', 8000, run_server)
    print("Serving HTTP on port 8000...")
    httpd.serve_forever()#发送给浏览器

html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Title</title>
</head>
<body>
    <h1>姓名:{{name}}</h1>#第一种写法
    <h1>爱好:</h1>
    <ul>
        {% for hobby in hobby_list %}#第二种写法循环键值对
        <li>{{hobby}}</li>
        {% endfor %}
    </ul>
</body>
</html>

answer

wsgiref framework

1569213829577

http requests and responses to a predetermined standard

get get the data submitted post data

1. The client web server connect link

2. Send http request

3. http server receives the request and returns a response

4. Release link tcp connection

The client browser parses html content

http divided into two

短链接和无连接 无状态
无连接发送完就断开链接,
无连接有两种模式
短链接
发送完数据等待几秒客户端的操作
无状态
不会保留状态

http

http协议
请求信息格式
GET / HTTP/1.1   请求行
Host: 127.0.0.1:8003  请求头
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36 
指定 浏览器格式
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
#空行br
请求数据  username=ziwen password=666


get请求 请求数据部分是没有数据的,get请求的数据在url上,在请求行里面,有大小限制,常见的get请求方式: 浏览器输入网址,a标签

post请求 请求数据在请求体(请求数据部分) ,数据没有大小限制, 常见方式:form表单提交数据
HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据.
以下是 HTTP 请求/响应的步骤:
1. 客户端连接到Web服务器
一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。例如,http://www.luffycity.com。
2. 发送HTTP请求
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。
3. 服务器接受请求并返回HTTP响应
Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。
4. 释放连接TCP连接
若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
5. 客户端浏览器解析HTML内容
客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。
````````````````````````````````````
在浏览器地址栏键入URL,按下回车之后会经历以下流程:

1.浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
2.解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接;
3.浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;(根据不同路径返回不同数据)
4.服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;
5.释放 TCP连接;(conn.close())因为tcp是长连接 http协议的特点
6.浏览器将该 html 文本并显示内容;  

Request method

Eight kinds of action

Common get post

#GET
//向指定的资源发出“显示”请求。使用GET方法应该只用在读取数据,而不应当被用于产生“副作用”的操作中,例如在Web Application中。其中一个原因是GET可能会被网络蜘蛛等随意访问。
#HEAD//
//与GET方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分。它的好处在于,使用这个方法可以在不必传输全部内容的情况下,就可以获取其中“关于该资源的信息”(元信息或称元数据)。
#POST
//向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求本文中。这个请求可能会创建新的资源或修改现有资源,或二者皆有。(把信息放入了请求数据)
PUT
//向指定资源位置上传其最新内容。
DELETE
//请求服务器删除Request-URI所标识的资源。
TRACE
//回显服务器收到的请求,主要用于测试或诊断。
OPTIONS
//这个方法可使服务器传回该资源所支持的所有HTTP请求方法。用'*'来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作。
#CONNECT
//HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接(经由加密的HTTP代理服务器)。
patch
局部更新数据

img

http status codes

1xx消息——请求已被服务器接收,继续处理
2xx成功——请求已成功被服务器接收、理解、并接受
3xx重定向——需要后续操作才能完成这一请求
4xx请求错误——请求含有词法错误或者无法被执行
5xx服务器错误——服务器在处理某个正确请求时发生错误

Redirect

例如一个http:jd.com/auth
1.输入 username和passwerd 提交数据
2.判断用户是否合法
3.如果是重定向 3xx
4.浏览器拿到网址,get请求获取对应的html
首页 http:www.jd.com

mvc framework and mtv

mvc
M --- models 数据库相关
v --- views 视图相关(逻辑)
C -- controller url控制器(url分发器,路由分发)
django-mtv
    M -- models 数据库相关
    T -- templates HTML相关 html就是模板
    V -- views  视图相关(逻辑)s
    + controller url控制器(url分发器,路由分发)

url

The default https port 443

http default port 80

Query parameters

?k1=v1&k2=v2

超文本传输协议(HTTP)的统一资源定位符将从因特网获取信息的五个基本元素包括在一个简单的地址中:
传送协议。
层级URL标记符号(为[////],固定不变)
访问资源需要的凭证信息(可省略) 
1.服务器。
    #//(通常为域名,有时为IP地址(dns解析))
2.端口号。
    //(以数字方式表示,若为HTTP的默认值“:80”可省略)
路径。
    //(以“/”字符区别路径中的每一个目录名称)
查询。
    //(GET模式的窗体参数,以“?”字符为起点,每个参数以“&”隔开,再以“=”分开参数名称与数据,通常以UTF8的URL编码,避开字符冲突的问题)
片段。(锚点)
    //以“#”字符为起点 
····································    
以http://www.luffycity.com:80/news/index.html?id=250&page=1 为例, 其中:
1.  http,是协议;
2.  www.luffycity.com,是服务器;
3.  80,是服务器上的网络端口号;
4.  /news/index.html,是路径;
5.  ?id=250&page=1,是查询。
大多数网页浏览器不要求用户输入网页中“http://”的部分,因为绝大多数网页内容是超文本传输协议文件。同样,“80”是超文本传输协议文件的常用端口号,因此一般也不必写明。一般来说用户只要键入统一资源定位符的一部分(www.luffycity.com:80/news/index.html?id=250&page=1)就可以了。

1569148055956

Common request headers

user_agent:用什么浏览器访问的网站 发送的请求
content-type:application/json或application 
#指定请求体的格式 (服务端按照格式要求进行解析)

Response format

url is 127.0.0.1 / path

You can not write a response header field when the reply can be customized response header

django request lifecycle

wsgi协议web服务网关接口
wsgi 是一种规范定义python的接口规范 可以搭配不同的应用程序
1.wsgiref本地做测试用,请求来了只能处理一个请求不能并发   
2.uwsgi linux和项目部署的时使用

浏览器向服务器请求数据(b/s架构)
本质是一个socket通信
1.浏览器请求发送到服务端 wsgi把接收到的请求 转发给django 
2.到达路由系统 进行路由匹配
3.到达视图进行业务处理 可以用orm从数据库中读取数据,调用模板进行渲染 渲染完成之后的字符串
4.通过wsgi 用send发送给客户端浏览器

Request (URL access, submit data, etc.) request
response (page reply, reply data, etc.) response

Download and install django

pip3 install django==1.11.23

Create a project django

Command Line

下载安装django

pip3 install django==1.11.23 
pip3 install django==1.11.23 http://mirrors.aliyun.com/pypi/simple/ 

创建项目
python36 manage.py runserver#开启django项目
python36 manage.py runserver 80 把端口号改成默认80
python36 manage.py runserver 0.0.0.0:80 其他人就可以访问了

创建app
python manage.py startapp app名称
指令船舰app需要的配置
项目的settings配置文件中,installapps的列表,添加一个app名称作为配置 
pycharm 创建完app之后,
如果在向创建新的app,需要指定创建app命令配置,
pycharm会自动配置app路径

Classification djnago the py file

1.manage.py ----- Django项目里面的工具,通过它可以调用django shell和数据库,启动关闭项目与项目交互等,不管你将框架分了几个文件,必然有一个启动文件,其实他们本身就是一个文件。
2.settings.py ---- 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量。
3.urls.py ----- 负责把URL模式映射到应用程序w。
4.wsgi.py ---- runserver命令就使用wsgiref模块做简单的web server,后面会看到renserver命令,所有与socket相关的内容都在这个文件里面了,目前不需要关注它。

Subproject document classification

views是写视图函数 视图类 代码逻辑

models是数据库的源 写与数据库相关的的

templatses 是模板 放置html xml等网络文件

wsgi用于书写socket

django basic operations

request对象 封装了所有请求  
request.method是当前请求方法 
````````````````````````````````````
.post 获取post请求的数据#请求体
.get 获取get请求的数据#问号以后的值
request.GET.get('pwd') 获取get 字典的值
request.POST.get('pwd')获取post 字典的值
post。get(“键”)取得的值是一个字符串
·······································

`````````````````````````````````````````````
注意'django.middleware.csrf.CsrfViewMiddleware',#安全机制

返回一个字典 获取值要把一个安全机制注释才能过

1569323222768

View function

视图函数
def articles(request,year,month): # 位置参数(形参) 2019 9
 print(year,type(year)) #2019 <class 'str'>  
#匹配出来的所有数据都是字符串
   print(month)
 return HttpResponse(year+'年'+ month +'月' +'所有文章')
 # 无名分组参数
    url(r'^articles/(\d+)/(\d+)/', views.articles), #articles/2019/9/

# 有名分组参数
url(r'^articles/(?P<xx>\d+)/(?P<oo>\d+)/', views.articles), #articles/2019/9/
#xx=2019  oo=9  关键字传参

def articles(request,oo,xx):  # 关键字传参 2019  9
    print(xx,type(xx)) #2019 <class 'str'>  #匹配出来的所有数据都是字符串
    print(oo)
    return HttpResponse(xx+'年'+ oo +'月' +'所有文章')

Famous grouping parameter

# 有名分组参数
url(r'^articles/(?P<xx>\d+)/(?P<oo>\d+)/', views.articles), #articles/2019/9/
#xx=2019  oo=9  关键字传参

def articles(request,oo,xx):  # 关键字传参 2019  9
    print(xx,type(xx)) #2019 <class 'str'>  #匹配出来的所有数据都是字符串
    print(oo)
    return HttpResponse(xx+'年'+ oo +'月' +'所有文章')

Nameless grouping parameter

 # 无名分组参数
url(r'^articles/(\d+)/(\d+)/', views.articles), #articles/2019/9/
正则分组/(\d+)/(\d+)/会把匹配的  一一对应单独存储一个变量
(\d+)正则贪婪 满足一个或多个整数

Specific examples

例如
html写法
<a href="/articles/2019/9">2019.9</a>#会把路径进行正则匹配 
#(要一一对应)
url(r"^articles/(\d+)/(\d+)/",views.articles),
#匹配的时候,返回对应的匹配的内容,
#articles是返回路径 后面匹配两个参数(正则匹配路径)

View function (request Request) supplemented

request是wsgirequest实例化的对象
1.print(request)打印出来的是--str--的返回值
requesrt这个对象含有————str————
#返回的都是字符串
2.print(request.path) #/home/  纯路径

3.print(request.path_info) #/home/  纯路径

4.print(request.get_full_path()) #/home/?a=1&b=2  全路径(不包含ip地址和端口)

5.print(request.body)  能够拿到请求数据部分的数据(post,get没有),get数据的内容在url里

6.print(request.META)
是一个Python字典,包含了所有本次HTTP请求的Header信息
查看需要在线json转换
user-agent返回

7.print(request.GET)返回get请求的数据类似字典的值
8.print(request.POST)返回get请求的数据类似字典的值
访问其他路径服务端会返回状态信息(状态码)

The method of the response in response to three

三个方法都需要模块的引用
底部都有一个httpResponse 把字符串传入页面
form django.shortcuts import render,HttpResponse,redirect
1.HTTPResponse('字符串')#传入一个字符串 向浏览器返回一个页面
render 和redirect都是通过httpresponse传递给浏览器 

2.render(request,'xx.html')返回浏览器一个xx.html
#模板渲染 模板就是html页面 渲染就是字符串替换
'''
示例
'''
#home.html页面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>24期官网</h1>
<h2>{{ namxx }}</h2>
</body>
</html>


#views视图.py (render有第三个参数是html传参使用)
def home(request):
    name = 'chao'
    return render(request, 'home.html',     {'namxx':name,})  #模板渲染(先把字符串替换了),这是在回复给浏览器之前做的事情
·······································

3.redirect redirection

Usage redirect (path) Example: redirect ( '/ index /')

A browser returns 3xx redirection returns a redirect ( '/ index /') path

redirect示例
浏览器访问/index/#例如127.0.0.1/index/
urls.py
from django.conf.urls import url
from django.contrib import admin
from Django_test import views#引用 视图函数模块
urlpatterns = [
   url(r'^index/', views.index),
]
def home(request):
    print('xxxxx')
    return redirect('/index/') #重定向路径

1569402912947

FBV and CBV view (view classes and functions)

FBV is a view function

def 函数名(request):
    函数体#进行判断
    return 要一个返回值返回给浏览器

CBV is the view class

urls written

url(r'^login',views.LoginView.as_view())
1.加载到这一句的时候LoginView这个类直接调用执行类方法,LoginView没有as_view方法 去父类View去寻找这个方法
2.执行完之后返回一个view方法名
3.相当于视图函数#执行url(r'^login',views.view)
4.等待源码调用view方法(函数)

views of the view class wording

from django.views import View#引用View方法
 class LoginView(View):#创建一个类 继承父类view
    def get(self,request):##处理get请求直接定义get方法,不需要自己判断请求方法了,源码中用dispatch方法中使用了反射来处理的
        print('小小小小')
        return render(request,'login.html')
    def post(self,request)

Simplified Analysis view source

执行步骤:
1.加载类名去调用执行as_view方法#views.loginview.as_view()#as_view
2.as_view返回一个view方法名
3.urls执行view方法
4.寻找到as_view函数里有view方法self = cls(**initkwargs)#实例化一个对象cls对应的就是 LoginView视图类
5. 继续往下执行return self.dispatch(request, *args, **kwargs)#这时self是LoginView视图类的实例化对象 去LoginView类中去寻找dispatch方法
6.LoginView视图类没有找到去对应的父类View去寻找
dispatch方法
7.找到http_method_names对应属性里面有各类方法
8.请求的方法名在这个属性中继续往下执行反射
9.利用反射去寻找对应的方法,如果找不到对应方法执行第三个参数报错
#注意
 getattr 第二个参数找不到就执行第三个参数 执行第三个方法直接报错返回 日志打印405


父类view
class View(object):

    http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    @classonlymethod
    def as_view(cls, **initkwargs):
        for key in initkwargs:
            if key in cls.http_method_names:
                raise TypeError("You tried to pass in the %s method name as a "
                                "keyword argument to %s(). Don't do that."
                                % (key, cls.__name__))
            if not hasattr(cls, key):
                raise TypeError("%s() received an invalid keyword %r. as_view "
                                "only accepts arguments that are already "
                                "attributes of the class." % (cls.__name__, key))
      2.#as_view里面有一个view方法
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            3.#实例化cls方法(就是LoginView视图类) 拿到自己类的对象
            if hasattr(self, 'get') and not hasattr(self, 'head'):
                self.head = self.get
            self.request = request
            self.args = args
            self.kwargs = kwargs
            return self.dispatch(request, *args, **kwargs)
        4.#执行到这发现 类调用一个方法 去视图类(LoginView)寻找dispatch方法,没有这个方法就去继承的父类去寻找 执行
        view.view_class = cls
        view.view_initkwargs = initkwargs

        update_wrapper(view, cls, updated=())

        update_wrapper(view, cls.dispatch, assigned=())
        return view 1.#返回一个view方法
    """
   dispatch方法
    """
5.找到dispatch方法执行
def dispatch(self, request, *args, **kwargs):
    #request.method.lower()取得请求对应的方法 方法名都是大写的所以需要小写对应
    #http_method_names去LoginView类去找,找不到去在源码中寻找(也就是继承的父类)
    if request.method.lower() in self.http_method_names:
        #请求的方法名在这个http_method_names属性中继续往下执行反射 
        #http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        #利用反射去寻找对应的方法
        #getattr 第二个参数找不到就执行第三个参数 执行第三个方法直接报错返回 日志打印405
    else:
        handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs)
#为什么第三个参数返回405
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
getattr 第二个参数找不到就执行第三个参数
'''http_method_not_allowed方法'''#为什么第三个参数返回405

def http_method_not_allowed(self, request, *args, **kwargs):
    logger.warning(
        'Method Not Allowed (%s): %s', request.method, request.path,
        extra={'status_code': 405, 'request': request}
    )
    return http.HttpResponseNotAllowed(self._allowed_methods())

The idea you want to execute some commands prior to distribution operations

Reconstruction of the parent class of its own distribution operations must be performed when the parent class

If there is no way he will complain

(Reconstructed parent dispatch methods)

from django.views import View
class LoginView(View):
    def dispatch(self,request,*args,**kwargs):
        print("xxx请求来了")
    ret=super(LoginView,self).dispatch(request,*args,**)
   重构父类(view)的dispatch方法
 #def dispatch(self, request, *args, **kwargs):
  # 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)
#执行对应方法 获得返回值 

    print("执行结束")
    return ret
#相当于执行return handler(request, *args, **kwargs)
    def get(self,request):
        print('xxxx')
        return render(request,"login.html")
    def post(self,request):
        print(request.POST)
        return HttpResponse('登录成功')

Diagram

1569416028460

Decorator

There are three ways

The method must be specified in the request class above

from django.utils.decorators import method_decorator
#必须引用django封装的装饰器
def wrapper(func):
    def inner(*args, **kwargs):
        print(11111)
        ret = func(*args, **kwargs)
        print(22222)

        return ret

    return inner

@method_decorator(wrapper,name='get')#第一种放松
class LoginView(View):
    def get(self,request):
        print('xxxx')
        return render(request,"login.html")

    @method_decorator(wrapper) #方式2
    def dispatch(self, request, *args, **kwargs):
        print('xx请求来啦!!!!')

        ret = super().dispatch(request, *args, **kwargs)

        print('请求处理的逻辑已经结束啦!!!')
        return ret

    @method_decorator(wrapper)#方式3
    def post(self,request):
         print(request.POST)
         return HttpResponse('登录成功')

Template Rendering

Guess you like

Origin www.cnblogs.com/strawberry-1/p/11666564.html