01-介绍

通用视图把视图开发中常用的写法和模式抽象出来,让你编写少量代码就能快速实现常见的数据视图。显示对象列表就是这样一种任务。

Django 自带的通用视图能实现下述功能:
1、列出对象并显示单个对象的详细信息。如果创建一个管理会议的应用程序,那么 TalkListView 和 Reg-
isteredUserListView 就是列表视图。某一个演讲的页面就是详细信息视图。 2、呈现基于日期的对象,显示为年月日归档页面(带有详细信息),以及“最新”页面。 3、让用户创建、更新和删除对象——需不需要授权都行。
# 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)
publication_date = models.DateField()

02-对象的通用视图-ListView

# views.py
from django.views.generic import ListView
from books.models import Publisher
class PublisherList(ListView):
model = Publisher
# 指定对应的模板
template_name = books/ publisher_list.html # urls.py
from django.conf.urls import url
from books.views import PublisherList
urlpatterns = [
url(r'^publishers/$', PublisherList.as_view()),
]
# 渲染这个模板时,上下文中有个名为 object_list 的变量,它的值是所有出版社对象。
{% extends "base.html" %}
{% block content %}
<h2>Publishers</h2>
<ul>
{% for publisher in object_list %}
<li>{{ publisher.name }}</li>
{% endfor %}
</ul>
{% endblock %}

03-指定模板上下文的名称 - context_object_name

# 默认的为 object_name

class PublisherList(ListView):
model = Publisher
context_object_name = 'my_favorite_publishers'

04-提供额外的上下文变量 - get_context_data

通常,除了通用视图提供的信息之外,还想显示一些额外信息。但是如何在模板中获取额外的信息呢?

答案是扩展 ListView、DetailView等,自己实现 get_context_data 方法。

默认的实现只为模板提供该显示的对象,不过可 以覆盖,提供更多信息:

from django.views.generic import DetailView
from books.models import Publisher, Book
class PublisherDetail(DetailView):
model = Publisher def get_context_data(self, **kwargs):
# 先调用原来的实现,获取上下文
context = super(PublisherDetail, self).get_context_data(**kwargs) # 把所有图书构成的查询集合添加到上下文中
context['book_list'] = Book.objects.all()
return context
提示:默认情况下,get_context_data 会把所有父类的上下文数据与当前类的合并在一起。如果在调 整上下文的子类中不想使用这种行为,要在超类上调用 get_context_data。
如果两个类没有在 上下文中定义相同的键,这样得到的结果符合预期。
但是,如果尝试覆盖超类设定的键(在调 用 super 之后),当子类想覆盖所有超类时,子类也必须在调用 super 之后显式设定那个键。

05-显示对象的子集 - queryset

from django.views.generic import DetailView
from books.models import Publisher class PublisherDetail(DetailView):
context_object_name = 'publisher'
# model = Publisher 其实是 queryset = Publisher.objects.all() 的简洁形式。
# 然而,使用 queryset 可以过滤 对象列表,进一步指定要在视图中查看的对象。如:过滤等
queryset = Publisher.objects.all()
from django.views.generic import ListView
from books.models import Book class BookList(ListView):
queryset = Book.objects.order_by('-publication_date')
context_object_name = 'book_list'

06-动态过滤 - get_queryset()

需求:根据 URL 中指定的键过滤列表页面中的对象。
解决方法:覆盖 ListView 的 get_queryset() 方法。它的默认实现是返回 queryset 属性的值,不过可以添加更多的逻辑。调用基于类的视图时,很多有用的东西存储到 self 中了,除了请 求(self.request)之外,还有根据 URL 配置捕获的位置参数(self.args)和关键字参数 (self.kwargs)。 # urls.py
from django.conf.urls import url
from books.views import PublisherBookList
urlpatterns = [
url(r'^books/([\w-]+)/$', PublisherBookList.as_view()),
] # views.py
from django.shortcuts import get_object_or_404
from django.views.generic import ListView
from books.models import Book, Publisher
class PublisherBookList(ListView):
template_name = 'books/books_by_publisher.html'
def get_queryset(self):
self.publisher = get_object_or_404(Publisher, name=self.args[0])
return Book.objects.filter(publisher=self.publisher)

如果需要,可以使用 self.request.user 通过当前用户过 滤,或者实现其他更复杂的逻辑。与此同时,我们还可以把出版社对象添加到上下文中,供模板使用:

def get_context_data(self, **kwargs):
# 先调用原来的实现,获取上下文
context = super(PublisherBookList, self).get_context_data(**kwargs)
# 添加出版社对象
context['publisher'] = self.publisher return context ## 执行额外的操作

07-在调用通用视图前后做些额外工作 - get_object()

假设 Author 模型中有个 last_accessed 字 段,用于记录这位作者的信息被人查看的最后时间:

# models.py
from django.db import models 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')
last_accessed = models.DateTimeField() # urls.py
from django.conf.urls import url
from books.views import AuthorDetailView
urlpatterns = [
#...
url(r'^authors/(?P<pk>[0-9]+)/$', AuthorDetailView.as_view(),
name='author-detail'),
] # views.py
from django.views.generic import DetailView
from django.utils import timezone
from books.models import Author class AuthorDetailView(DetailView):
queryset = Author.objects.all()
def get_object(self):
# 调用超类中的同名方法
object = super(AuthorDetailView, self).get_object()
# 记录最后访问日期 object.last_accessed = timezone.now() object.save()
# 返回对象
return object # 注意:这里,URL 配置使用的分组名为 pk,这是 DetailView 过滤查询集合时查找主键所用的默认名称。
# 如果把这个分组命名为其他值,要在视图中设定 pk_url_kwarg。详情参见 DetailView 的文档。

Django之通用视图的更多相关文章

  1. Django创建通用视图函数

    想在我们有两个视图: def thinkingview(request): user = request.user if request.method == 'GET': return render( ...

  2. Django入门-通用视图

    文档:https://docs.djangoproject.com/en/1.11/topics/class-based-views/ from django.shortcuts import get ...

  3. django 类通用视图详解

    view() :     该类为所有类视图的父类,处于最底层,仅仅只对请求参数做校验后,给特定请求方法做特定调用. 用法: url中定位到类方法:Aa.as_view() ——> View.as ...

  4. 5 第一个Django第4部分(表单和通用视图)

    上一节完成了视图编写,这一节为应用添加投票功能,也就是表单提交. 5.1编写一个简单的表单 5.2使用通用视图 5.3改良视图 5.1编写一个简单的表单 在网页设计中添加Form元素 polls/te ...

  5. Django 1.10中文文档-第一个应用Part4-表单和通用视图

    本教程接Part3开始.继续网页投票应用程序,并将重点介绍简单的表单处理和精简代码. 一个简单表单 更新一下在上一个教程中编写的投票详细页面的模板polls/detail.html,让它包含一个HTM ...

  6. 基于类的通用视图(Class-based generic views)

    在web开发中,最令人头痛的就是一遍又一遍的重复固定的模式.在解决了模板层面和模型层面的重复代码之痛之后,Django使用通用视图来解决视图层面的代码重复. 扩展通用视图 毫无疑问通用视图可以大幅度地 ...

  7. Django_通用视图(五)

    参考官网的投票系统,按照综合案例的流程创建应用polls,主要模块代码如下: test1/polls/models.py import datetime from django.db import m ...

  8. Django 1.6 基于类的通用视图

    Django 1.6 基于类的通用视图 最初 django 的视图都是用函数实现的,后来开发出一些通用视图函数,以取代某些常见的重复性代码.通用视图就像是一些封装好的处理器,使用它们的时候只须要给出特 ...

  9. django 创建一个通用视图

    创建一个通用视图   抽取出我们代码中共性的东西是一个很好的编程习惯. 比如,像以下的两个Python函数:     def say_hello(person_name): print 'Hello, ...

随机推荐

  1. MySQL安装步骤及环境变量配置

    MySQL安装 MySQL下载地址:http://dev.mysql.com/downloads/installer/1:首先进入的是安装引导界面2:然后进入的是类型选择界面,这里有3个类型:Typi ...

  2. 七:mvc使用CodeFirst(代码优先)创建数据库

    1. 理解EF CodeFirst模式特点 2. 使用CodeFirst模式生成数据库 1. CodeFirst模式(代码优先) Code First是Entity Framework提供的一种新的编 ...

  3. STM32唯一ID(Unique Device ID)的读取方法

    每一个STM32微控制器都自带一个96位的唯一ID,也就是Unique Device ID或称为UID,这个唯一ID在任何情况下都是唯一的且不允许修改.    在开发过程中,可能需要用到这个UID,比 ...

  4. SQLite3学习笔记(2)

      SQLite 创建表 SQLite 的CREATE TABLE 语句用于在任何指定的数据库创建一个新表. 创建新表,涉及到命名表.定义列及每一行的数据类型. CREATE TABLE 的基本语法如 ...

  5. 说一下 HashMap 的实现原理?(未完成)

    说一下 HashMap 的实现原理?(未完成)

  6. set调用add报错:

    Map<String, String> goodsStandMap = new HashMap<>();goodsStandMap.put("key1", ...

  7. 说说lock到底锁谁(II)?

    摘要 今天在园子里面有园友反馈关于[C#基础]说说lock到底锁谁?文章中lock(this)的问题.后来针对文章中的例子,仔细想了一下,确实不准确,才有了这篇文章的补充,已经对文章中的demo进行修 ...

  8. 计数dp做题笔记

    YCJS 3924 饼干 Description 给定一个长度为\(n\)的序列,序列每个元素的取值为\([1,x]\),现在给定\(q\)个区间,求在所有取值方案中,区间最小值的最大值的期望是多少? ...

  9. PHP mysqli_fetch_field_direct() 函数

    返回结果集中某个单一字段(列)的 meta-data,并输出字段名称.表格和最大长度: mysqli_fetch_field_direct(result,fieldnr); 参数 描述 result ...

  10. BZOJ 4070: [Apio2015]雅加达的摩天楼 根号分治+spfa

    此题卡Dijkstra... Code: #include <bits/stdc++.h> #define N 30005 #define M 4000000 #define ll lon ...