目录

Django基础-视图

bookandmusic
bookandmusic 2021年01月23日  ·  阅读 5

django中的逻辑处理主要是在视图(views)中完成,而视图分为两类:函数视图(FBV)和类视图(CBV)。

视图

一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应。

响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。

放置在项目(project)或应用程序(app)目录中的名为views.py的文件中。

下面是一个以 HTML 文档的形式返回当前日期和时间的视图:

from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

让我们来逐行解释下上面的代码:

首先,我们从 django.http模块导入了HttpResponse类,以及Python的datetime库。

接着,我们定义了current_datetime函数。它就是视图函数。每个视图函数都使用HttpRequest对象作为第一个参数,并且通常称之为request

注意,视图函数的名称并不重要;不需要用一个统一的命名方式来命名,以便让Django识别它。
我们将其命名为current_datetime,是因为这个名称能够比较准确地反映出它实现的功能。

这个视图会返回一个HttpResponse对象,其中包含生成的响应。

Django使用请求和响应对象来通过系统传递状态。

当浏览器向服务端请求一个页面时,Django创建一个HttpRequest对象,该对象包含关于请求的元数据。然后,Django加载相应的视图,将这个HttpRequest对象作为第一个参数传递给视图函数。

每个视图负责返回一个HttpResponse对象。

FBV

基本用法

  • function based view 基于函数的视图
from django.shortcuts import HttpResponse
import datetime


def mul(request):
    now = datetime.datetime.now()
    return HttpResponse(now)
  • 路由映射
from django.conf.urls import path
from app01 import views


urlpatterns = [
    upathrl(r'mul/', views.mul),
]

装饰器

FBV 本身就是一个函数,所以和给普通的函数加装饰器无差:

from django.shortcuts import HttpResponse
import time


def wrapper(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        ret = func(*args, **kwargs)
        end_time = time.time()
        print("used:", end_time-start_time)
        return ret
    return inner


# FBV版添加装饰器
@wrapper
def add_class(request):
    now = datetime.datetime.now()
    return HttpResponse(now)

扩充

如果客户端直接向服务器提交post请求,没有携带csrf_token参数,就会出现403,禁止提交。

如果想要绕过csrf验证,有两种选择,一种就是,直接关闭中间件;另一种,就是在视图中,使用csrf装饰器跳过验证。

from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import HttpResponse

@csrf_exempt
def test(request):
    name = request.POST.get("name")
    return HttpResponse(name)

CBV

基本用法

  • class based view 基于类的视图
from django.views import View
from django.shortcuts import HttpResponse


# 处理不同请求方式的逻辑清晰明了
class AddPublisher(View):
    def get(self,request):
        """处理get请求"""
        return HttpResponse("GET 请求")
    
    def post(self,request):
        """处理post请求"""
        return HttpResponse("POST 请求")  
  • 路由映射
#urls.py 文件
from django.conf.urls import path
from app01 import views

urlpatterns = [
	path(r'add_publisher/', views.AddPublisher.as_view()),
]  # 固定写法注意.as_view()是要加括号的

执行流程

CBV 如何获取页面请求类型, 并响应的

  1. 项目启动,执行AddPublisher.as_view() ——> view

    path('add_publisher/',views.AddPublisher.as_view())
    
  2. 请求到来时执行view函数:

    1. 实例化AddPublisher ——》 self

    2. self.request = reqeust

    3. 执行self.dispatch(request,*args,**kwargs)

      1. 判断请求方式是否被允许 http_method_names = []

        1. 允许:通过反射获取到当前请求方式对应的方法 ——> handler

        2. 不允许:self.http_method_not_allowed ——> handler

      2. 执行handler(request,*args,**kwargs) ——> 返回响应

装饰器

  • 类中的方法与独立函数不完全相同,因此不能直接将函数装饰器应用于类中的方法 ,我们需要先将其转换为方法装饰器。
  • Django 中提供了 method_decorator 装饰器用于将函数装饰器转换为方法装饰器。

装饰器加在类方法上

import time
from django.views import View
from django.utils.decorators import method_decorator   #导入method_decorator装饰器

def timer(func):
    def inner(request, *args, **kwargs):
        start = time.time()
        ret = func(request, *args, **kwargs)
        print("函数执行的时间是{}".format(time.time() - start))
        return ret
    return inner

class AddClass(View):

    @method_decorator(timer)  # 将函数装饰器转换为方法装饰器
    def get(self,request):
        """处理get请求"""
        return HttpResponse("GET 请求")
    
    def post(self,request):
        """处理post请求"""
        return HttpResponse("POST 请求")  

dispatch() 加装饰器

使用CBV时要注意,请求过来后会先执行dispatch()这个方法,如果需要对该视图类的所有请求方法做批量处理,就可以在dispatch()方法上加装饰器,在所有的请求方法中都生效

import time
from django.views import View
from django.utils.decorators import method_decorator   #导入方法装饰器

def timer(func):
    def inner(request, *args, **kwargs):
        start = time.time()
        ret = func(request, *args, **kwargs)
        print("函数执行的时间是{}".format(time.time() - start))
        return ret
    return inner

class Login(View):
    
    @method_decorator(timer) #相当于给get,post请求都加上了装饰器
    def dispatch(self, request, *args, **kwargs):
        obj = super(Login,self).dispatch(request, *args, **kwargs)
        return obj
 
    def get(self,request):
        """处理get请求"""
        return HttpResponse("GET 请求")
    
    def post(self,request):
        """处理post请求"""
        return HttpResponse("POST 请求")  

装饰器加在类上

import time
from django.views import View
from django.utils.decorators import method_decorator 

def timer(func):
    def inner(request, *args, **kwargs):
        start = time.time()
        ret = func(request, *args, **kwargs)
        print("函数执行的时间是{}".format(time.time() - start))
        return ret
    return inner

@method_decorator(timer,name = 'get')  # 相当于给get请求,加上了装饰器
@method_decorator(timer,name = 'post')  # 相当于给post请求,加上了装饰器
class Login(View):
    
    def get(self,request):
        """处理get请求"""
        return HttpResponse("GET 请求")
    
    def post(self,request):
        """处理post请求"""
        return HttpResponse("POST 请求")  
分类: Python
标签: django