通用显示视图
通用显示视图旨在显示数据。在许多项目中,他们通常是最常用的视图。
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 即可实现。
示例
使用默认参数
#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: 2024-08-22T22:32:17+08:00</p> <p>Date: 2024-08-22T22:32:17+08:00</p> <!-- 默认上下文传递对象为object -->
自定义
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: 2024-08-22T22:32:17+08:00</p> <p>Date: 2024-08-22T22:32:17+08:00</p> <!-- 默认上下文传递对象为object -->
自定义
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: 2024-08-22T22:32:17+08:00</p> <p>Date: 2024-08-22T22:32:17+08:00</p> <!-- 抛弃默认object,使用自定义上下文传递对象名article -->
总结
DetailView
主要用在获取某个model
的单个对象中- 通过
template_name
属性来指定需要渲染的模板 - 通过
context_object_name
属性来指定获取的model
对象的名字,否则只能通过默认的object
获取 - 复写
get_object
方法以增加获取单个 model 对象的其他逻辑 - 复写
get_context_data
方法来为上下文对象添加额外的变量以便在模板中访问