Loading

Django视图层

一、视图函数

一个视图函数,简称视图,它是一个python函数,接受web请求并且返回web响应,响应可以是html文件、重定向、错误、图片等 ......。

视图层中有两个重要对象:请求对象(request)和响应对象(HttpResponse)。

请求对象

请求对象(HttpRequest):Django把http请求报文中的内容主体分装到了HttpRequest对象中,并把这个对象当做参数传递给了视图函数中的第一个参数,一般这个参数我们都定义成request。

请求对象的常用属性和方法:

  • .method:——获取请求使用的方法(GET/POST)
  • .GET:————获取get请求提交的数据
  • .POST:———获取post请求提交的数据
  • .META:———获取请求头相关信息
  • .body:———byte类型,request.POST 的数据就是从body里提取的
  • .path:——获取url地址的路径部分,只包含路径部分
  • .path_info:——获取url地址的完整路径,既包含路径又包含参数部分
  • .FILES:——类似于字典对象,包含所有的上传文件信息(post提交)。
  • .get_full_path( ):——返回用户访问的URL包括get请求参数
  • .is_secure( ):——判断请求是否通过 HTTPS 发起的。是则返回True
  • .is_ajax( ):——如果请求是通过XMLHttpRequest 发起的,则返回True
# views.py文件
from django.shortcuts import render, reverse, HttpResponse

def index(request):				# http相关请求信息会传递给——>request
    if request.method == 'GET':
        print(request.GET)		# 获取GET请求提交的数据
        print(request.META)		# 请求头相关信息,就是一个大字典
        print(request.path)		# /index/ 路径
        print(request.path_info)# /index/ 路径
        print(request.get_full_path())	# /index/?user=xiaoyang
        
        return render(request,'index.html')
    else:
        print(request.body)		# post请求的原始数据 b'user=xiaoyang'
        print(request.POST)		# 获取POST提交的数据

响应对象

Django最后一定会响应一个HttpResponse的示例对象

三种形式:

  1. HttpResponse( ' 字符串 ' )——> 最简单

  2. render( ‘ 页面 ’ )——> 最重要

    • 两个功能

    —— 读取文件字符串

    —— 嵌入变量(模板渲染)html里面

  3. redirect():——> 重定向

重定向状态码301和302的区别

  • 相同之处:

    301和302都表示重定向,会自动跳转到一个新的URL地址。

  • 不同之处

    301表示旧地址的资源已经被永久移除了,就是这个资源不可访问了。

    302表示旧地址还存在,这个资源任然可以访问,这个重定向只是临时的转到另一个URL地址

重定向的原因:

  1. 调整网站(如改变网页目录结构)
  2. 网页被迁移到一个新的地址
  3. 网页扩展名改变(如应用需要把.php改成.html或.shtml)

HttpResponse ——> 回复字符串的时候使用

redirct ——> 重定向

def login(request):
    ...
    return redirect('/index/')

render ——> 回复一个HTML页面的时候使用

render(request, template_name[, context])
       
参数:
1、request:用于生成响应的请求对象,固定必须传入的第一个参数
2、template_name:要使用的模板的完整名称,必须传入,render默认会去templates目录下查找模板文件
3、context:可选参数,可以传入一个字典用来替换模块文件中的变量

render的功能可以总结为:根据给定字典渲染模板文件,并返回一个渲染后的 HttpResponse对象。

实例:

# views.py文件
from django.shortcuts import render, redirect, HttpResponse

def login(request):
    # 当为GET请求时就返回登录页面
    if request.method == 'GET':
        return render(request, 'login.html')
    else:
        # post 请求时,就提取出请求数据。
        user = request.POST.get('username')
        pwd = request.POST.get('password')
        if user == 'xiaoyang' and pwd == '123':
            # 重定向到/index/路径
            return redirect(/index/)
        else:
            return HttpResponse('登录失败')

def index(request):
    return HttpResponse('登录成功!!!')

二、FBV和CBV

Django的视图层是由两种形式构成的:FBV和CBV

FBV

之前写的就是 FBV基于函数的视图(Function Base View)

# views.py文件
from django.shortcuts import render

def index(request):
    return render(request, 'index.html')

FBV加装饰器

FBV本身就是一个函数,所以和普通函数加装饰器一样。

# views.py文件
from django.shortcuts import render, HttpResponse

def wapper(func):
    def inner(*args, **kwargs):
        print('请求之前')
        ret = func(*args, **kwargs)
        print('请求之后')
        return ret
    return inner

@wapper
def login(request):
    return render(request, 'login.html')

CBV

CBV基于类的视图(Class Base View)

实例:

# urls.py文件
from django.urls import path, re_path
from app01 import views

urlpatterns = [
                        # 必须调用类中的as_view()方法
    re_path(r'^login/', views.Login_View.as_view())
]

# ------------------------------------------------------

# views.py文件
from django.shortcuts import render, HttpResponse
from django.views import View	# 需要手动导入

class Login_View(View):	# 必须继承View类

    # 当请求url为:http://127.0.0.1:8000/login/会先触发dispatch的执行
    def dispatch(self, request, *args, **kwargs):
        """
        请求前的预处理操作
        """
        # 必须执行父类的dispatch方法
        obj = super().dispatch(request, *args, **kwargs)
        """
        请求后的操作
        """
        return obj	# 必须返回obj

    # get请求对应的操作
    def get(self, request):
        return render(request, 'login.html')

    # post请求对应的操作
    def post(self, request):
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        if user == 'xiaoyang' and pwd == '123':
            return HttpResponse('登录成功!!!')
        else:
            return HttpResponse('登录失败!!!')

CBV加装饰器

在CBV中加装饰器不能直接将函数装饰器应用于类中的方法,因为类中的方法和独立函数完全不相同,因此我们需要先将其转换为方法装饰器。

Django提供了 method_decorator 装饰器用于将函数装饰器转换为方法装饰器。

实例:

方式一:装饰在get方法上面

# views.py文件
from django.shortcuts import render, HttpResponse
# 需要手动导入
from django.utils.decorators import method_decorator
from django.views import View

def wapper(func):
    def inner(*args, **kwargs):
        print('请求之前')
        ret = func(*args, **kwargs)
        print('请求之后')
        return ret
    return inner

class Login_View(View):
    
    # 将装饰器写入括号内
    @method_decorator(wapper)
    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):
        return HttpResponse('post方法...')

方法二:给所有的方法加装饰器

这个是装饰在父类的dispatch方法上面,所以它先执行装饰器函数,然后调用了父类的dispatch类属性,最后才执行的我我们的类方法

实例:

# views.py文件
from django.shortcuts import render, HttpResponse
# 需要手动导入
from django.utils.decorators import method_decorator
from django.views import View

def wapper(func):
    def inner(*args, **kwargs):
        print('请求之前')
        ret = func(*args, **kwargs)
        print('请求之后')
        return ret
    return inner

class Login_View(View):

    @method_decorator(wapper)   # 装饰在dispatch上面
    def dispatch(self, request, *args, **kwargs):
        obj = super().dispatch(*args, **kwargs)
        return obj

    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):
        return HttpResponse('post方法...')

方式三:装饰在class上可以通过属性名指定要装饰的方法

这个装饰的是指定的方法,所以先调用了父类的dispatch方法执行装饰函数。

# views.py文件
from django.utils.decorators import method_decorator
from django.views import View

def wapper(func):
    def inner(*args, **kwargs):
        print('请求之前')
        ret = func(*args, **kwargs)
        print('请求之后')
        return ret
    return inner

@method_decorator(wapper,name='get')
class Login_View(View):
    def get(self):
        pass    
    def post(self):
        pass

posted @ 2021-06-09 19:04  Mr-Yang`  阅读(122)  评论(0编辑  收藏  举报