• TemplateView , ListView ,DetailView三种常用类视图用法


    1.1 视图混合介绍

      1MixinView的职能区分

          1. Mixin提供数据,View提供模板和渲染,所以一般get_context_data在Mixin中,get(),post(),head()在View中
          2. Mixin和View不是能随意组合的,必须要注意他们之间的方法的解析顺序,也就是MRO

      2ContextMixin

          1. 直接就是一个get_context_data,用于返回context数据。

      3View

          1. 会调用所有的get方法,post方法,具体是这些['get', 'post', 'put', 'delete', 'head', 'options', 'trace']
          2. View中是没有返回一个response的,所以光继承View的话,必须要重写get等,以返回一个response。

      4TemplateResponseMixin

          1. 故名思议,这个Mixin会加入Template的基本信息,也就是template的名字

          2. 但是光有Template信息是没有用的,因为她没有跟View想联系起来,如果想要跟View联系起来的话必须想
              办法把render_to_response插进MRO的调用顺序,而且TemplateResponseMixin是没有context的信息的

          3. 有一个可以借鉴的方法就是TemplateView的做法, Mixin和View把原来的试图函数中的三个东西分开了
            模板(TemplateResponseMixin),
            上下文数据(ContextMixin),
            负责将这些联系起来的一个东西(View)

      5TemplateView

          1. TemplateView就继承自TemplateResponseMixin,ContextMixin以及View,所以它的调用思路就很明确了
          2. 在其中定义一个get方法,然后通过get方法去将上面的三个东西联系在一起.
          3. 我们可以看一下TemplateView的源代码

    1.2 TemplateView 基本使用

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^home/', views.HomePageView.as_view(),name='home'),
    ]
    urls.py
    from django.db import models
    
    class Article(models.Model):
        name = models.CharField(max_length=32)
        age = models.SmallIntegerField()
    
        def __str__(self):
            return self.name
    app01/models.py
    from django.views.generic.base import TemplateView
    from app01.models import Article
    
    class HomePageView(TemplateView):
    
        template_name = "home.html"               #视图返回的页面
    
        def get_context_data(self, **kwargs):     #向上下文变量中添加额外的数据
            context = super(HomePageView, self).get_context_data(**kwargs)
            context['latest_articles'] = Article.objects.all()[:5]
            print(context)
            return context
    
    # 返回给前端页面字典,context内容
    context = {'latest_articles':"<QuerySet [<Article: zhangsan>, <Article: lisi>, <Article: wangwu>]>", # 表中获取的数据
               'view':" <app01.views.HomePageView object at 0x06A2B470>"}                                # 视图返回的页面
    app01/views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>home</h1>
    
        {% for article in latest_articles%}
            {{article.name}}
        {% endfor %}
        
    </body>
    </html>
    home.html

     

    1.3 ListView

    参考官网: https://docs.djangoproject.com/en/2.0/ref/class-based-views/generic-display/#listview

    参考博客: https://www.zmrenwu.com/post/33/

      1、ListView作用

          作用:ListView 作用是按照指定方式向数据库获取表中数据

      2、ListView使用举例

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^home/', views.HomePageView.as_view(),name='home'),
    ]
    urls.py
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    from django.db import models
    
    class Article(models.Model):
        name = models.CharField(max_length=32)
        age = models.SmallIntegerField()
    
        def __str__(self):
            return self.name
    app01/models.py
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    
    from django.shortcuts import render
    from django.views.generic import ListView
    
    from app01.models import Article
    
    class HomePageView(ListView):
        template_name = 'home.html'
        model = Article
        context_object_name = 'article_list'    # 指定获取的模型列表数据保存的变量名
    
        def get_queryset(self, ):
            '''get_queryset函数常处理对数据库表查询结果'''
            print self.request.GET                      # GET请求的所有参数都可以在这里获取
    
            queryset = self.model.objects.all()[:2]      # 根据GET请求的条件对Article表进行过滤
            return queryset
    
        def get_context_data(self, **kwargs):
            '''get_context_data 可以携带其他信息,就如常规中设置的字典'''
            print self.request.GET                      # GET请求的所有参数都可以在这里获取
    
            context = super(HomePageView, self).get_context_data(**kwargs)
            context['k1'] = 'v1'
            context['k2'] = 'v2'
            return context
    app01/views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>home</h1>
        <!--1、后端如果设置:context_object_name = 'article_list' 这里就可以获取到值了 -->
        <div>
            {% for article in article_list%}
                {{article.name}}
            {% endfor %}
        </div>
    
        <!--2、如果后端没有设置 context_object_name 默认表查询的queryset=object_list -->
        <div>
            {% for object in  object_list %}
                {{object.name}}
            {% endfor %}
        </div>
    
        <!--3、后端通过context传的字典直接可以获取 -->
        <p>{{ k1 }}</p>
        <p>{{ k2 }}</p>
    </body>
    </html>
    home.html

     

    1.4 DetailView

      1、DetailView作用

          1) 除了从数据库中获取模型列表的数据外,从数据库获取模型的一条记录数据也是常见的需求。

          2) 比如查看某篇文章的详情,就是从数据库中获取这篇文章的记录然后渲染模板,DetailView 专门提供了这种功能

    blog/views.py
    
    from django.views.generic import ListView, DetailView
    
    # 记得在顶部导入 DetailView
    class PostDetailView(DetailView):
        # 这些属性的含义和 ListView 是一样的
        model = Post
        template_name = 'blog/detail.html'
        context_object_name = 'post'
    
        def get(self, request, *args, **kwargs):
            # 覆写 get 方法的目的是因为每当文章被访问一次,就得将文章阅读量 +1
            # get 方法返回的是一个 HttpResponse 实例
            # 之所以需要先调用父类的 get 方法,是因为只有当 get 方法被调用后,
            # 才有 self.object 属性,其值为 Post 模型实例,即被访问的文章 post
            response = super(PostDetailView, self).get(request, *args, **kwargs)
    
            # 将文章阅读量 +1
            # 注意 self.object 的值就是被访问的文章 post
            self.object.increase_views()
    
            # 视图必须返回一个 HttpResponse 对象
            return response
    
        def get_object(self, queryset=None):
            # 覆写 get_object 方法的目的是因为需要对 post 的 body 值进行渲染
            post = super(PostDetailView, self).get_object(queryset=None)
            post.body = markdown.markdown(post.body,
                                          extensions=[
                                              'markdown.extensions.extra',
                                              'markdown.extensions.codehilite',
                                              'markdown.extensions.toc',
                                          ])
            return post
    
        def get_context_data(self, **kwargs):
            # 覆写 get_context_data 的目的是因为除了将 post 传递给模板外(DetailView 已经帮我们完成),
            # 还要把评论表单、post 下的评论列表传递给模板。
            context = super(PostDetailView, self).get_context_data(**kwargs)
            form = CommentForm()
            comment_list = self.object.comment_set.all()
            context.update({
                'form': form,
                'comment_list': comment_list
            })
            return context
    DetailView
  • 相关阅读:
    okhttp之源码学习1
    Retrofit2之源码解析2
    Retrofit2之源码解析1
    retrofit之笔记内容
    retrofit之基本笔记
    retrofit之基本内容
    rxjava-源码分析
    rxjava-基本内容解析
    rxjava_几类转换
    java几种常见的编码
  • 原文地址:https://www.cnblogs.com/jiaxinzhu/p/12571901.html
Copyright © 2020-2023  润新知