本文整理自网络,侵删。
内置基于类的通用视图
编写Web应用程序可能是单调的,因为我们一次又一次地重复某些模式。Django试图消除模型和模板层的某些单调性,但Web开发人员也在视图级别上遇到这种无聊的情况。
开发了Django的通用视图来缓解这种痛苦。它们采用了视图开发中发现的某些常见习语和模式,并对它们进行了抽象,以便您可以快速编写数据的通用视图而无需编写太多代码。
我们可以识别某些常见任务,例如显示对象列表,并编写显示任何对象列表的代码。然后,可以将所讨论的模型作为附加参数传递给URLconf。
Django附带了通用视图以执行以下操作:
- 显示单个对象的列表和详细信息页面。如果我们正在创建一个用于管理会议的应用程序,则a TalkListView和a RegisteredUserListView将是列表视图的示例。单个对话页就是所谓的“详细”视图的示例。
- 在年/月/日归档页面,关联的详细信息和“最新”页面中显示基于日期的对象。
- 允许用户创建,更新和删除对象(无论有无授权)。
这些视图加在一起提供了执行开发人员遇到的最常见任务的界面。
扩展通用视图
毫无疑问,使用通用视图可以大大加快开发速度。但是,在大多数项目中,有时通用视图不再足够了。确实,新Django开发人员提出的最常见问题是如何使通用视图处理更广泛的情况。
这是为1.3版本重新设计通用视图的原因之一-以前,它们是带有令人困惑的选项列表的视图函数;现在,与其在URLconf中传递大量配置,不如建议扩展常规视图的方法是将其子类化并覆盖其属性或方法。
也就是说,通用视图将受到限制。如果您发现自己很难将视图实现为通用视图的子类,则可能会发现使用自己的基于类或功能的视图来只编写所需的代码会更有效。
某些第三方应用程序中提供了更多通用视图的示例,或者您可以根据需要编写自己的视图。
对象的通用视图
TemplateView当然是有用的,但是当涉及到呈现数据库内容的视图时,Django的通用视图确实非常出色。因为这是一项常见的任务,所以Django附带了一些内置的通用视图,以帮助生成对象的列表和详细视图。
让我们先来看一些显示对象列表或单个对象的示例。
我们将使用以下模型:
# models.py
from django.db import models
?
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
?
class Meta:
ordering = ["-name"]
?
def __str__(self):
return self.name
?
class Author(models.Model):
salutation = models.CharField(max_length=10)
name = models.CharField(max_length=200)
email = models.EmailField()
headshot = models.ImageField(upload_to='author_headshots')
?
def __str__(self):
return self.name
?
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField('Author')
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
publication_date = models.DateField()
现在我们需要定义一个视图:
# views.py
from django.views.generic import ListView
from books.models import Publisher
?
class PublisherList(ListView):
model = Publisher
最后,将该视图挂接到您的网址中:
# urls.py
from django.urls import path
from books.views import PublisherList
?
urlpatterns = [
path('publishers/', PublisherList.as_view()),
]
这就是我们需要编写的所有Python代码。但是,我们仍然需要编写一个模板。我们可以通过在视图中添加一个template_name属性来明确地告诉视图使用哪个模板 ,但是在没有显式模板的情况下,Django将从对象名称中推断出一个模板。在这种情况下,推断的模板将是"books/publisher_list.html"-“书”部分来自定义模型的应用程序的名称,而“发布者”位是模型名称的小写版本。
注意:因此,当(例如)将 后端的APP_DIRS选项DjangoTemplates设置为True in时TEMPLATES,模板位置可以是:/path/to/project/books/templates/books/publisher_list.html
将针对包含名为的变量的上下文呈现此模板,该变量 object_list包含所有发布者对象。模板可能如下所示:
{% extends "base.html" %}
?
{% block content %}
<h2>Publishers</h2>
<ul>
{% for publisher in object_list %}
<li>{{ publisher.name }}</li>
{% endfor %}
</ul>
{% endblock %}
这就是全部。通用视图的所有很酷的功能都来自更改通用视图上设置的属性。该 通用视图引用文档中的所有详细的通用视图的选择; 本文档的其余部分将考虑一些您可以自定义和扩展通用视图的常用方法。
制作“友好的”模板上下文
您可能已经注意到我们的示例发布者列表模板将所有发布者存储在名为的变量中object_list。尽管这很好用,但对模板作者并不是那么“友好”:他们必须“只是知道”他们在这里与发行人打交道。
好吧,如果您要处理模型对象,那么已经为您完成了。当您处理对象或查询集时,Django可以使用模型类名称的小写形式填充上下文。除了默认object_list条目之外,还提供了此条目,但包含完全相同的数据,即publisher_list。
如果仍然不能很好地匹配,则可以手动设置上下文变量的名称。context_object_name通用视图上的属性指定要使用的上下文变量:
# views.py
from django.views.generic import ListView
from books.models import Publisher
?
class PublisherList(ListView):
model = Publisher
context_object_name = 'my_favorite_publishers'
提供有用context_object_name的东西总是一个好主意。您设计模板的同事将感谢您。
添加额外的上下文
通常,您需要提供一些超出通用视图所提供信息的额外信息。例如,考虑在每个出版商详细信息页面上显示所有书籍的列表。该DetailView 通用视图提供了出版商到上下文,但是我们如何在模板中获取更多的信息?
答案是子类化DetailView 并提供您自己的get_context_data方法实现。默认实现将要显示的对象添加到模板中,但是您可以覆盖它以发送更多内容:
from django.views.generic import DetailView
from books.models import Book, Publisher
?
class PublisherDetail(DetailView):
?
model = Publisher
?
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super().get_context_data(**kwargs)
# Add in a QuerySet of all the books
context['book_list'] = Book.objects.all()
return context
注意:通常,get_context_data将所有父类的上下文数据与当前类的上下文数据合并。若要在要更改上下文的自己的类中保留此行为,请务必确保调用 get_context_data超类。当没有两个类尝试定义相同的键时,这将提供预期的结果。但是,如果任何类在父类设置了键之后都尝试覆盖键(在调用super之后),则该类的所有子级也需要在super之后显式设置键,以确保覆盖所有父键。如果遇到问题,请查看视图的方法解析顺序。
相关阅读 >>
更多相关阅读请进入《Django》频道 >>

Python编程 从入门到实践 第2版
python入门书籍,非常畅销,超高好评,python官方公认好书。