通用显示视图

通用显示视图旨在显示数据。在许多项目中,他们通常是最常用的视图。

ListView

引入

from django.views.generic.list import ListView

介绍

显示对象列表的页面。

当此视图正在执行时,self.object_list将包含视图正在操作的对象列表(使用默认的context_object_name的情况下)。

祖先

  • django.views.generic.list.MultipleObjectTemplateResponseMixin
  • django.views.generic.base.TemplateResponseMixin
  • django.views.generic.list.BaseListView
  • django.views.generic.list.MultipleObjectMixin
  • django.views.generic.base.View

类属性及方法

  • template_name : 指定需要渲染的模板
  • model: 指定获取数据的model属性
  • context_object_name: 给get_queryset方法返回的 model 列表重新命名的,因为默认返回的 model 列表其名字是object_list,为了可读性,我们可以通过context_object_name来重新指定
  • get_queryset():获取此视图的项目列表。当我们需要自定义列表数据时,可以通过重写此函数来完成。如果无需自定义,则只需指定一个model属性,告诉Django去获取那个model的列表就可以了。
  • get_context_data(): 这个方法是用来给传递到模板文件的上下文对象(context)添加额外的内容

示例:

#views.py
class IndexView(ListView):
    template_name = "blog/index.html"
    context_object_name = "article_list"
    model = Article #指定model属性,Django会去获取Article的全部数据列表
#views.py
class IndexView(ListView):
    template_name = "blog/index.html"
    context_object_name = "article_list"

    def get_queryset(self): #自定义数据列表,将article_list里的article进行了markdown拓展。
        article_list = Article.objects.all()
        for article in article_list:
            article.body = markdown2.markdown(article.body, extras=['fenced-code-blocks'], )
        return article_list

    def get_context_data(self, **kwargs):
        kwargs['category_list'] = Category.objects.all().order_by('name')
        return super(IndexView, self).get_context_data(**kwargs)
#urls.py
from django.urls import path

from article.views import ArticleListView

urlpatterns = [
    path('article/', ArticleListView.as_view(), name='article-list'),
]
<!-- blog/index.html -->
<h1>Articles</h1>
<ul>
{% for article in article_list %}
    <li>{{ article.pub_date|date }} - {{ article.headline }}</li>
{% empty %}
    <li>No articles yet.</li>
{% endfor %}
<h1>Category</h1>
<ul>
{% for category in category_list %}

{% empty %}
    <li>No category yet.</li>
{% endfor %}
</ul>

总结

  • ListView主要用在获取某个model列表
  • 通过template_name属性来指定需要渲染的模板
  • 通过context_object_name属性来指定获取的model列表的名字,否则只能通过默认的object_list获取
  • 复写get_queryset方法以增加获取model列表的其他逻辑
  • 复写get_context_data方法来为上下文对象添加额外的变量以便在模板中访问

DetailView

引入

from django.views.generic.detail import DetailView

介绍

表示显示单个对象详情的界面。

当此视图正在执行时,self.object将包含视图正在操作的对象(使用默认的context_object_name的情况下)。

祖先

  • django.views.generic.detail.SingleObjectTemplateResponseMixin
  • django.views.generic.base.TemplateResponseMixin
  • django.views.generic.detail.BaseDetailView
  • django.views.generic.detail.SingleObjectMixin
  • django.views.generic.base.View

类属性及方法

  • model: 告诉 Django是获取哪个model对应的单个对象.
  • pk_url_kwarg: 视图过滤参数。告诉Django通过model的哪一个field进行数据筛选。默认为pk,即获取URLconf中参数为pk的值来获取model中的数据。
  • slug_url_kwarg: 与pk_url_kwarg用途一致。默认为slug,即获取URLconf中参数为slug的值来获取model中的数据。
  • get_object(): 默认情况下获取 id 为pk_url_kwarg 的对象,如果需要在获取过程中对获取的对象做一些处理,比如对文章做 markdown 拓展,通过复写 get_object 即可实现。

示例

  1. 使用默认参数

     #views.py
     from django.views.generic.detail import DetailView
     from django.utils import timezone
    
     from articles.models import Article
    
     class ArticleDetailView(DetailView):
         model = Article
    
     #urls.py
     from django.urls import path
    
     from article.views import ArticleDetailView
    
     urlpatterns = [
         #使用默认pk_url_kwarg, 参数应为pk
         path('<int:pk>', ArticleDetailView.as_view(), name='article-detail'),
         #或者使用默认slug_url_kwarg,参数应为slug,且model中应该存在slug属性字段
         path('<slug:slug>/', ArticleDetailView.as_view(), name='article-detail'),
     ]
    
     <!-- article_detail.html -->
     <h1></h1>
     <p></p>
     <p>Reporter: </p>
     <p>Published: 2022-08-28T07:45:11+00:00</p>
     <p>Date: 2022-08-28T07:45:11+00:00</p>
     <!-- 默认上下文传递对象为object -->
    
  2. 自定义pk_url_kwarg

     #views.py
     from django.views.generic.detail import DetailView
     from django.utils import timezone
    
     from articles.models import Article
    
     class ArticleDetailView(DetailView):
         model = Article
         pk_url_kwarg = 'article_id' #自定义传递参数
    
         def get_object(self, queryset=None): #重写父类get_object来对article进行markdown拓展
             obj = super(ArticleDetailView, self).get_object() #父类get_object函数中会通过Article.objects.get(pk=article_id参数传递的值)来获取object
             obj.body = markdown2.markdown(obj.body, extras=['fenced-code-blocks'], )
             return obj
    
     #urls.py
     from django.urls import path
    
     from article.views import ArticleDetailView
    
     urlpatterns = [
         #应与自定义传递参数一致
         path('<int:article_id>', ArticleDetailView.as_view(), name='article-detail'),
     ]
    
     <!-- article_detail.html -->
     <h1></h1>
     <p></p>
     <p>Reporter: </p>
     <p>Published: 2022-08-28T07:45:11+00:00</p>
     <p>Date: 2022-08-28T07:45:11+00:00</p>
     <!-- 默认上下文传递对象为object -->
    
  3. 自定义slug_url_kwarg

     #views.py
     from django.views.generic.detail import DetailView
     from django.utils import timezone
    
     from articles.models import Article
    
     class ArticleDetailView(DetailView):
         model = Article
         context_object_name = "article" 自定义上下文传递对象名,见html中使用
         slug_field = 'name' #自定义Article过滤的field
         slug_url_kwarg = 'article_name' #自定义传递参数
    
         def get_object(self, queryset=None): #重写父类get_object来对article进行markdown拓展
             obj = super(ArticleDetailView, self).get_object() #父类get_object函数中会通过Article.objects.get(name=article_name参数传递的值)来获取object,这里的name对应slug_filed定义的值
             obj.body = markdown2.markdown(obj.body, extras=['fenced-code-blocks'], )
             return obj
    
     #urls.py
     from django.urls import path
    
     from article.views import ArticleDetailView
    
     urlpatterns = [
         #应与自定义传递参数一致
         path('<slug:article_name>', ArticleDetailView.as_view(), name='article-detail'),
     ]
    
     <!-- article_detail.html -->
     <h1></h1>
     <p></p>
     <p>Reporter: </p>
     <p>Published: 2022-08-28T07:45:11+00:00</p>
     <p>Date: 2022-08-28T07:45:11+00:00</p>
     <!-- 抛弃默认object,使用自定义上下文传递对象名article -->
    

总结

  • DetailView主要用在获取某个model的单个对象中
  • 通过template_name属性来指定需要渲染的模板
  • 通过context_object_name属性来指定获取的model对象的名字,否则只能通过默认的object获取
  • 复写get_object方法以增加获取单个 model 对象的其他逻辑
  • 复写get_context_data方法来为上下文对象添加额外的变量以便在模板中访问
Copyright © itrunner.cn 2020 all right reserved,powered by Gitbook该文章修订时间: 2022-08-28 07:44:16

results matching ""

    No results matching ""