• 34.Django视图


    1.Django视图FBV和CBV

    1.1 FBV的使用

    FBV(function base views)
    就是在视图里使用函数处理请求
    在子应用的url:

    
    from django.contrib import admin
    from django.urls import path
    from . import views
    urlpatterns = [
        path('fbv/', views.fbv_func),
    ]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在子应用的views:

    from django.shortcuts import render, HttpResponse
    
    # Create your views here.
    def fbv_func(request):
        return HttpResponse('fbv方式处理请求')
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在主应用的url中

    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('view_app/',include('view_app.urls'))
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 视图函数 current_datetime,每个视图函数都将一个HttpRequest 对象作为其第一个参数,该参数通常被命名request
    • 视图函数的名称无关紧要,它不必以某种方式命名,以便Django能够识别它,但是函数命名一定要能够清晰的描述它的功能
    • 视图函数返回一个HttpResponse响应的对象,每个视图函数负责返回一个HttpResponse对象(有例外,但我们在稍后讨论)

    1.2 CBV的使用

    通过类的方式,类中编写函数,函数名为发送请求方式。在url配置中,会被as_view()函数识别出来,发送的是哪一种请求。
    子应用url中

    from django.contrib import admin
    from django.urls import path
    from . import views
    urlpatterns = [
        path('cbv/', views.CBVClass.as_view())
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    子应用views中

    from django.shortcuts import render, HttpResponse
    from django.views import View
    class CBVClass(View):
        # 发送get请求
        def get(self,request):
            return HttpResponse('cbv方式处理,调用get方法')
        # 发送post请求,会被as_view()自动识别
        def post(self, request):
            return HttpResponse('cbv方式处理,调用post方法')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • CBV提供了一个as_view()静态方法(也就是类方法),调用这个方法,会创建一个类的实例,然后通过实例调用dispatch()方法,dispatch()方法会根据request的method的不同调用相应的方法来处理request(如get(),post()等)
    • 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
    • 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多 if 判断,可以提高代码可读性

    2.Django视图返回错误响应

    def error_test(request, error_id):
        if error_id>30:
            # 方法1:使用HttpResponseNotFound
            # HttpResponseNotFound(f'HttpResponseNotFound error_id{error_id}')
            return HttpResponse(f'HttpResponse error_id{error_id}')
        elif error_id > 20:
            # 方法2:使用状态码:status
            return HttpResponse(f'HttpResponse error_id{error_id}',status=404)
        elif error_id >10:
            # 方法3:使用http404
            raise Http404('http404')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3.视图装饰器

    3.1概述

    @require_http_methods,要求视图只接收指定的http方法

    @require_GET():仅仅允许GET方法

    @require_POST():仅仅允许POST方法.

    @require_safe():仅仅允许GET和HEAD方法
    @login_required

    必须登录才能访问装饰的视图函数,

    用户未登录,则重定向到settings.LOGIN_URL,除非指定了login_url参数,例如:@login_required(login_url=‘/polls/login/’)

    3.2 代码展示

    视图views

    from django.shortcuts import render, HttpResponse
    from django.views import View
    from django.http import Http404
    from django.views.decorators.http import *
    from django.contrib.auth.decorators import login_required
    # 视图装饰器1:require_http_methods要求视图只接收指定的http方法
    # @require_GET
    # @require_POST 效果同上
    @require_http_methods(['POST',"GET"])
    def decorator_func(request):
        # return HttpResponse(f'HttpResponse GET请求')
        # return HttpResponse(f'HttpResponse POST请求')
        return HttpResponse(f'HttpResponse GET或者是POST请求')
    
    # 方法2:登录装饰器,必须登录才能访问装饰的视图函数,如果未登录,直接重定向到settings.LOGIN_URL,除非制定了login_url参数
    # 使用方法1:配置settings
    # 使用方法2:指定login_url参数
    # @login_required # 方法1
    @login_required(login_url='/view_app/notlogin/')
    def detail(request):
        return HttpResponse('访问详情页')
    def notlogin(request):
        return HttpResponse('未登录,请先登录')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    url路由

    from django.contrib import admin
    from django.urls import path
    from . import views
    urlpatterns = [
        path('fbv/', views.fbv_func),
        path('cbv/', views.CBVClass.as_view()),
        path('error/', views.error_test),
        path('decorator/', views.decorator_func),
        path('detail/', views.detail),
        path('notlogin/', views.notlogin)
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    settings配置

    # 未登录访问路由
    LOGIN_URL = '/view_app/notlogin'
    
    • 1
    • 2

    4.HTTPRequest对象

    1. HttpRequest
      每一个用户请求在到达视图函数的同时,django会自动创建一个HttpRequest对象并把这个对象当做第一个参数传给要调用的views方法。HttpRequest对象里封装了本次请求所涉及的用户浏览器端数据、服务器端数据等,在views里可以通过request对象来调用相应的属性。
      所有视图函数的第一个参数都是HttpRequest实例
      属性(除非另有说明,否则所有属性均应视为只读):
    • HttpRequest.scheme:
      表示请求使用的协议(http或https)

    • HttpRequest.body:
      原始HTTP请求主体,类型是字节串。处理数据一些非html表单的数据类型很有用,譬如:二进制图像,XML等;

      • 取form表单数据,请使用 HttpRequest.POST
      • 取url中的参数,用HttpRequest.GET
    • HttpRequest.path:
      表示请求页面的完整路径的字符串,不包括scheme和域名。
      例: “/music/bands/the_beatles/”

    • HttpRequest.path_info:

      在某些Web服务器配置下,主机名后的URL部分被分成脚本前缀部分和路径信息部分。path_info无论使用什么Web服务器,该属性始终包含路径的路径信息部分。使用此代替path可以使代码更容易在测试和部署服务器之间移动。

      例如,如果WSGIScriptAlias你的应用程序设置为 “/minfo”,则path可能是"/minfo/music/bands/the_beatles/" , path_info 会是 “/music/bands/the_beatles/”。

    • HttpRequest.method:

      表示请求中使用的HTTP方法的字符串,是大写的。例如:

      if request.method == 'GET':
          do_something()
      elif request.method == 'POST':
          do_something_else()
      
      • 1
      • 2
      • 3
      • 4
    • HttpRequest.encoding:

      表示当前编码的字符串,用于解码表单提交数据(或者None,表示使用该DEFAULT_CHARSET设置)。

      可以设置此属性来更改访问表单数据时使用的编码,修改后,后续的属性访问(例如读取GET或POST)将使用新encoding值。

    • HttpRequest.content_type:

      表示请求的MIME类型的字符串,从CONTENT_TYPE解析 。

    • HttpRequest.content_params:

      包含在CONTENT_TYPE 标题中的键/值参数字典。

    • HttpRequest.GET:

      包含所有给定的HTTP GET参数的类似字典的对象。请参阅QueryDict下面的文档。

    • HttpRequest.POST:

      包含所有给定HTTP POST参数的类似字典的对象,前提是请求包含表单数据。请参阅QueryDict文档。POST不包含文件信息,文件信息请见FILES。

    • HttpRequest.COOKIES:

      包含所有Cookie的字典,键和值是字符串。

    • HttpRequest.FILES:

      包含所有上传文件的类似字典的对象

    • HttpRequest.META:

      包含所有可用HTTP meta的字典

    中间件设置的属性:

    ​ Django的contrib应用程序中包含的一些中间件在请求中设置了属性。如果在请求中看不到该属性,请确保使用了相应的中间件类MIDDLEWARE。

    • HttpRequest.session:

      来自SessionMiddleware:代表当前会话的可读写字典对象。

    • HttpRequest.site:

      来自CurrentSiteMiddleware: 代表当前网站的实例Site或 RequestSite返回get_current_site()

    • HttpRequest.user:
      来自AuthenticationMiddleware:AUTH_USER_MODEL代表当前登录用户的实例

    4.1代码测试

    def request_test(request):
        print('scheme:', request.scheme)
        print('path:', request.path)
        print('method:', request.method)
        print('META:',request.META)
        return HttpResponse('request_test')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5.QueryDict的使用

    在HttpRequest对象中,GET和POST属性是django.http.QueryDict实例,该对象定义未相同的键的多个值的字典状态,继承自MultiValueDict,而MultiValueDict则继承自dict
    简单来说,QueryDict就是用于接收GET请求传递的参数值,会有各种方式进行接收
    代码展示
    url:http://127.0.0.1:8000/view_app/query_dict/?a=100&b=20&a=99

    def query_dict(request):
        values = request.GET #接收成一个对象的形式
        a = values.get('a') # 这样可以获取,但是展示出来,只会显示最后一个
        b = values['b']
        alist = values.getlist('a')
        items = values.items()
        print('values-------------',values)
        return HttpResponse(f'query_dict: a:{a}, b:{b}, alist:{alist}, items{list(items)}')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    打印结果为:values-------------
    前端http展示为:query_dict: a:99, b:20, alist:[‘100’, ‘99’], items[(‘a’, ‘99’), (‘b’, ‘20’)]

    6.HttpResponse对象

    用作了解,多是在设置
    返回给浏览器端的响应对象

    属性:

    • HttpResponse.content:

      表示响应的字符串

    • HttpResponse.charset:

      表示响应将被编码的字符集,如果在HttpResponse实例化时没有给出,则会从中提取 content_type,如果没有设置content_type,则使用settings.DEFAULT_CHARSET

    • HttpResponse.status_code:

      该响应的 HTTP 状态码

    • HttpResponse.reason_phrase:

      响应的HTTP原因描述语,使用HTTP标准的默认原因描述语
      除非明确设置,否则reason_phrase由 status_code 决定。

    • HttpResponse.streaming:

      总是False,中间件通过此属性可以区分流式响应与常规响应

    • HttpResponse.closed:

      如果response已经结束,则返回True,否则返回False

    7.JsonResponse对象

    包含json格式内容的响应

    def json_test(request):
        json_value = {
            'userName':'lili',
            'age':24
        }
        return JsonResponse(json_value)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    前端展示:{“userName”: “lili”, “age”: 24}

    8.FileResponse对象

    访问文件、图片的对象使用FileResponse

    from django.shortcuts import render, HttpResponse
    from django.views import View
    from django.http import Http404,JsonResponse, HttpResponseNotFound, FileResponse
    from django.views.decorators.http import *
    from django.contrib.auth.decorators import login_required
    def file_test(request):
        import os
        path = os.getcwd() + "/" + "a.jpg"
        print('path------------:',path) # 获取到当前目录的上一级
        return FileResponse(open(path,'rb'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    9.render方法的使用

    • 必需的参数:

    ​ request:用于生成此响应的请求对象。

    ​ template_name:要使用的模板的全名或模板名称的列表。

    • 可选参数:

    ​ context:要添加到模板上下文的值的字典。默认情况下,这是一个空字典。如果字典中的值是可调用的,视图将在渲染模板之前调用它。

    ​ content_type:用于生成文档的MIME类型。默认为DEFAULT_CONTENT_TYPE设置的值。

    ​ status:响应的状态码。默认为200。

    ​ using:用于加载模板的模板引擎名。

    1. 配置settings
    # 加入子应用的地址,选择True,,若在主应用找不到templates会到子应用中找
    INSTALLED_APPS = [
        'view_app'
    ]
    import os
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR,'templates')],
            'APP_DIRS': True,
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. 配置路由
    2. 编写函数
    def render_test(request):
        # 方法1:(推荐)
        # return render(request, "render_test.html",{'username':'张三','age':25},content_type='text/html')
        # 方法2:
        t = loader.get_template('render_test.html')
        c = {'username':'张三','age':25}
        return HttpResponse(t.render(c, request), content_type='text/html')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    10.redirect重定向

    url地址:

    
    from django.contrib import admin
    from django.urls import path
    from . import views
    app_name = 'view_app'
    urlpatterns = [
        path('fbv/', views.fbv_func),
        path('cbv/', views.CBVClass.as_view()),
        path('error/', views.error_test, name='error_test'),
        path('decorator/', views.decorator_func),
        path('detail/', views.detail),
        path('notlogin/', views.notlogin),
        path('request_test/', views.request_test),
        path('query_dict/', views.query_dict),
        path('json_test/', views.json_test),
        path('file_test/', views.file_test),
        path('render_test/', views.render_test, name='render_test'),
        path('redirect_test/', views.redirect_test)
    ]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    views编写

    def redirect_test(request):
        # 不带参数的重定向
        # return redirect('render_test')
        # 若存在命名空间,必须添加名称;若带参数,必须携带参数
        return redirect('view_app:error_test',error_id=29)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    11.get_object_or_404的使用

    当我们查询某个数据时候,若获取失败,则返回一个404页面
    ​ 必需的参数:

    ​ klass:一Model类或一个Manager或QuerySet从哪个实例来获取对象

    ​ **kwargs:查找参数,应该采用get()或filter()的参数。
    views:

    def get_object_or_404_test(request,id):
        question = get_object_or_404(Question, pk=id)
        return render(request, 'question.html',{'question':question})
    
    • 1
    • 2
    • 3

    ps:需要创建好数据库模型,数据表,并连接数据库

    11.内置通用视图

    ​ 包含在 from django.views import generic 中
    ​ 具体视图类型有:

    __all__ = [
        'View', 'TemplateView', 'RedirectView', 'ArchiveIndexView',
        'YearArchiveView', 'MonthArchiveView', 'WeekArchiveView', 'DayArchiveView',
        'TodayArchiveView', 'DateDetailView', 'DetailView', 'FormView',
        'CreateView', 'UpdateView', 'DeleteView', 'ListView', 'GenericViewError',
    ]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ​ 比较常用的:RedirectView、DetailView、ListView

    ​ 用法:
    例如DetailView:类的使用方法和函数的使用方法
    VIews中

    from django.shortcuts import render, HttpResponse, redirect, get_object_or_404
    from django.views import View
    from django.http import Http404,JsonResponse, HttpResponseNotFound, FileResponse
    from django.views.decorators.http import *
    from django.contrib.auth.decorators import login_required
    from django.template import loader
    from view_app.models import Question
    from django.views import generic
    class Question_Detail(generic.DetailView):
        model = Question
        template_name = "question_detail.html"
    
    def question_detail_func(request, id):
        question = Question.objects.get(pk=id)
        return render(request, 'question_detail.html',{'object':question})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    url路由:

    
    from django.contrib import admin
    from django.urls import path
    from . import views
    # app_name = 'view_app'
    urlpatterns = [    path('get_object_or_404_test//',views.get_object_or_404_test),
        path('question_detail//',views.Question_Detail.as_view()), #类的使用必须名称为pk
        path('question_detail_func//',views.question_detail_func) # 函数使用时名称无所谓
    ]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    templates:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <ul>
            <!-- 获取视图传递的数据必须是object来获取 -->
            <li>question_text:{{object.question_text}}</li>
            <li>pub_date:{{object.pub_date}}</li>
        </ul>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    小程序如何设置各种时间参数
    Vue-Electron初始化项目及打包
    如果企业商标被抢注了,该怎么追回?
    文科类文献综述怎么写?
    objective-c 基础学习
    事务、存储引擎
    2022年广西壮族自治区中职网络安全技能竞赛“Linux操作系统渗透测试详解”
    私有git仓库只支持http情况下go mod tidy 和 go get 默认走https的问题处理 GOINSECURE
    AVL树和2-3-4树详解
    《Solidity 简易速速上手小册》第7章:智能合约的部署与交互(2024 最新版)
  • 原文地址:https://blog.csdn.net/m0_63953077/article/details/127925698