码迷,mamicode.com
首页 > 其他好文 > 详细

Django框架基本原理1

时间:2018-04-02 01:05:01      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:word   handle   utf8   __name__   type   color   图片   生命周期   完成   

Django之请求的本质

  1. 本质上django程序就是一个socket服务端,用户的浏览器其实就是一个socket客户端;

  2. 在遵循http协议的基础上两方进行通讯;

    以django为例: 涉及到底层socket方面(接收和解析浏览器的请求信息, 响应头和响应体的发送都是由django的wsgi模块完成的,用户只需要实现路由和视图函数,模板等代码部分即可):

  3. 请求头和请求体以两个\r\n分隔开, 请求头的内容也是以\r\n分开, 相应头和响应体同理;

  4. Cookie信息是在请求头和响应头中存放的;

// 在浏览器输入 http://127.0.0.1:8001/ 即可看到发送的信息
import socket

def handle_request(client):
    # 相当于接收用户信息,在做出相应的反馈...
    buf = client.recv(1024)

    # response(响应头和响应体)
    client.send("HTTP/1.1 200 OK\r\n\r\n<h1 style=‘color:red‘>Hello, yuan</h1>".encode("utf8"))

    # 响应体也可以分开写
    # client.send("<h1 style=‘color:red‘>Hello, yuan</h1>".encode("utf8"))

def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((‘localhost‘, 8002))
    sock.listen(5)

    while True:
        connection, address = sock.accept()
        # 处理用户信息
        handle_request(connection)
        connection.close()


if __name__ == ‘__main__‘:
    main()

自定义web框架

可以将这个三部分分为放在三个文件中,在bin主代码区导入urls和view函数即可;

# views文件 -------------------------------
def f1(request):
    f = open("alex.html", ‘rb‘)
    data = f.read()
    f.close()
    return [data]

def f2(request):
    f = open("egon.html", ‘rb‘)
    data = f.read()
    f.close()
    return [data]

def log_in(request):
    f = open("login.html", ‘rb‘)
    data = f.read()
    f.close()
    return [data]

def auth(request):
    data = request.get(‘QUERY_STRING‘).strip().split("&")
    username = data[0].split("=")[1]
    password = data[1].split("=")[1]
    print(username, password)
    if username=="alex" and password=="abc123":
        return [b"login success"]
    else:
        return [b"wrong username or password"]

def register(request):
    f = open("register.html", ‘rb‘)
    data = f.read()
    f.close()
    return [data]


# urls文件  ----------------------------------
def routers():
    URLpattern = [
        ("/alex", f1),
        ("/egon", f2),
        ("/login", log_in),
        ("/auth", auth),
        ("/register", register)
    ]
    return URLpattern


# bin文件   ---------------------------------
from wsgiref.simple_server import make_server
from .urls import routers

def application(environ, start_response):
    # 1. 接收请求, 所有的请求信息都保存在environ对象中
    path = environ.get("PATH_INFO") # 取出请求的文件路径名称

    # 2. 向浏览器返回响应信息(响应头信息)
    start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/html‘)])
    url_patterns = routers()  # 取出url和函数的键值对

    # 3. 循环遍历(url)键值对,若匹配则赋值对应的函数
    func = None
    for item in url_patterns:
        if path == item[0]:
            func = item[1]
            break

    if func:
        # 4. 调用视图函数, 返回响应体信息
        return func(environ) # 注意,这里必须return调用函数,否则会报错!
    else:
        return [b"<h1>404</h1>"]  # 列表中, 元素是二进制字节

s = make_server("127.0.0.1", 8800, application)
s.serve_forever()

Django之请求的生命周期

Django的请求生命周期是指当用户在浏览器上输入url到用户看到网页的这个时间段内,Django程序内部所发生的事情;
具体步骤如下:

  1. 当用户在浏览器输入url时, 然后浏览器会生成请求头和请求体发送给服务器;
  1. url经过wsgi---中间件---最后到达路由映射表, 按顺序进行正则匹配,若匹配到,则进入对应的视图函数或者类(CBV)中;
  2. 视图函数根据客户端的请求,取出数据并渲染到模板中,其中可能涉及ORM操作(增删改查)或从缓存取出数据, 最终以字符串的形式返回;

技术分享图片


CBV模式

工作原理

  1. 一个url对应一个视图类
  2. 用户提交HTTP请求之后, 经过过wsgi和中间件,最后到URL路由, 再判断出是走哪个类,接着进入views相关的类, 然后此类调用父类的dispatch(),dispatch会根据http请求头里的methodget还是post方法来执行相应的函数

Dispatch结合session实现用户授权访问

方法1: 直接在类中重载dispaych方法

弊端: 代码重复使用!

from django.views import View

class LoginView(View):
    def get(self, request):
        return render(request, ‘login.html‘)
    def post(self, request):
        request.session[‘user_info‘] = {‘username‘: ‘bob‘, ‘info‘: ‘‘}
        return redirect(‘/index.html‘)


class IndexView(View):
    def dispatch(self, request, *args, **kwargs):
        # 不存在session信息则直接跳转至登录界面
        if not request.session.get(‘user_info‘, ‘‘):
            return redirect(‘/login.html‘)
        ret = super(IndexView, self).dispatch(request, *args, **kwargs)
        return ret
        
    def get(self, request):
        return render(request, ‘index.html‘)
方法2: 使用装饰器

内置的装饰器csrf_exempt是特例,只能装饰dispatch函数才能起到作用,是的post请求无须通过csrf中间件的验证

from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt

def test(func):
    """装饰器函数"""
    def inner(*args, **kwargs):
        return func(*args, **kwargs)
    return inner


class LoginView(View):
    # 方式1,作用于dispatch函数
    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        ret = super(LoginView, self).dispatch(request, *args, **kwargs)
        print(‘login after‘)
        return ret

    # 方式2: 装饰get函数
    # @method_decorator()
    def get(self, request):
        return render(request, ‘login.html‘)

    # @method_decorator(csrf_exempt)
    def post(self, request):
        username = request.POST.get(‘username‘, ‘‘)
        password = request.POST.get(‘password‘, ‘‘)
        if username and password:
            request.session[‘user_info‘] = {‘user‘:username, ‘pwd‘:password}
            return redirect(‘/index.html‘)
        else:
            return render(request, ‘login.html‘)

# @method_decorator(func)
class IndexView(View):
    def dispatch(self, request, *args, **kwargs):
        if not request.session.get(‘user_info‘):
            return redirect(‘/login.html‘)
        ret = super(IndexView, self).dispatch(request, *args, **kwargs)
        return ret

    def get(self, request):
        return render(request, ‘index.html‘)

Django框架基本原理1

标签:word   handle   utf8   __name__   type   color   图片   生命周期   完成   

原文地址:https://www.cnblogs.com/fqh202/p/8689180.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!