Django - 通用视图
Django - 通用视图
Section titled “Django - 通用视图”编写视图(view)有时会涉及重复的样板代码(boilerplate code),特别是在处理常见任务时,如显示对象列表、显示单个对象的详细信息或处理简单表单。Django 的通用视图(generic views,它们是基于类的视图,简称 CBVs)为这些常见模式提供了预构建的解决方案,让你可以少写代码。
通用视图是位于 django.views.generic 中的 Python 类。你通常可以在 URLconf 中直接使用它们,或者在 views.py 文件中继承它们以定制其行为。
常见的通用视图类:
Section titled “常见的通用视图类:”- 显示视图:
TemplateView:渲染给定的模板,可包含可选的上下文(context)。ListView:渲染对象列表(通常来自数据库查询)。DetailView:渲染单个对象的详细信息。- 编辑视图:
FormView:渲染和处理表单。CreateView:显示用于创建新对象的表单并处理保存。UpdateView:显示用于编辑现有对象的表单并处理保存。DeleteView:显示确认页面并处理删除现有对象。- 基于日期的视图: (
ArchiveIndexView,YearArchiveView,MonthArchiveView等),用于显示基于日期的对象。
示例 1:显示静态页面(TemplateView)
Section titled “示例 1:显示静态页面(TemplateView)”假设你有一个简单的 about.html 模板要显示。
方法 1:直接在 urls.py 中使用
from django.urls import pathfrom django.views.generic import TemplateView
urlpatterns = [ path('about/', TemplateView.as_view(template_name='myapp/about.html'), name='about'), # ... other URLs]方法 2:在 views.py 中继承(如果你需要添加额外的上下文,这将非常有用)
from django.views.generic import TemplateView
class AboutView(TemplateView): template_name = 'myapp/about.html'
# Optional: Add extra context data # 可选:添加额外的上下文数据 def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['page_title'] = 'About Us' return contextfrom django.urls import pathfrom .views import AboutView
urlpatterns = [ path('about/', AboutView.as_view(), name='about'), # ... other URLs]在上面两种情况下,访问 /myapp/about/ 都将渲染 myapp/templates/myapp/about.html 模板。
示例 2:列出对象(ListView)
Section titled “示例 2:列出对象(ListView)”让我们列出假设的 Article 模型中的所有条目。
# myapp/models.py (Hypothetical)# myapp/models.py (假设)from django.db import modelsfrom django.urls import reverse
class Article(models.Model): title = models.CharField(max_length=200) content = models.TextField() pub_date = models.DateTimeField(auto_now_add=True)
def __str__(self): return self.title
def get_absolute_url(self): return reverse('article_detail', kwargs={'pk': self.pk})使用 ListView:
from django.views.generic import ListViewfrom .models import Article
class ArticleListView(ListView): model = Article # Specify the model to list # 指定要列出的模型 template_name = 'myapp/article_list.html' # Optional: Defaults to myapp/article_list.html # 可选:模板名称 (默认为 myapp/article_list.html) context_object_name = 'articles' # Optional: Name in template context (default: object_list) # 可选:在模板上下文中的变量名 (默认为 object_list) ordering = ['-pub_date'] # Optional: Order the results # 可选:结果排序 paginate_by = 5 # Optional: Enable pagination # 可选:启用分页,每页显示 5 个from django.urls import pathfrom .views import ArticleListView
urlpatterns = [ path('articles/', ArticleListView.as_view(), name='article_list'), # ... other URLs like article_detail # ... 其他 URL,例如 article_detail]模板(myapp/templates/myapp/article_list.html):
<!-- myapp/templates/myapp/article_list.html --><h1>Articles</h1>
<ul>{% for article in articles %} {# Use context_object_name here #}{# 在这里使用 context_object_name #} <li> <a href="{{ article.get_absolute_url }}">{{ article.title }}</a> (Published: {{ article.pub_date|date:"Y-m-d" }}) (发布日期:{{ article.pub_date|date:"Y-m-d" }}) </li>{% empty %} <li>No articles have been published yet.</li> <li>暂无已发布的文章。</li>{% endfor %}</ul>
{# Add pagination controls if using paginate_by #}{# 如果使用了 paginate_by,添加分页控件 #}{% if is_paginated %} <div class="pagination"> <span class="step-links"> {% if page_obj.has_previous %} <a href="?page=1">« first</a> <a href="?page={{ page_obj.previous_page_number }}">previous</a> {% endif %}
<span class="current"> Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}. 第 {{ page_obj.number }} 页,共 {{ page_obj.paginator.num_pages }} 页。 </span>
{% if page_obj.has_next %} <a href="?page={{ page_obj.next_page_number }}">next</a> <a href="?page={{ page_obj.paginator.num_pages }}">last »</a> {% endif %} </span> </div>{% endif %}访问 /myapp/articles/ 将显示按发布日期排序的、带分页的文章列表。
通用视图显著减少了常见任务所需的代码量,促进了 DRY(Don’t Repeat Yourself,不要重复自己)原则的应用并加快了开发速度。有关更多详情和定制选项,请参阅 Django 关于基于类的视图的文档。