文档章节

django类视图浅析

人间四月
 人间四月
发布于 2016/04/19 09:45
字数 1431
阅读 17
收藏 0
点赞 1
评论 0

在Django1.3之前,通用视图是以函数的方式来实现的。基于函数的实现已经不 建议使用,建议使用这里介绍的基于类的实现方式。

基于类的通用视图(以及任何继承了Django提供的基础类的基于类的视图)都能够以下面两种方式被配置:子类化,或者直接通过URLconf来传递参数。

简单使用

当你子类化一个类视图时,你可以重写一些属性(比如template_name)或者 一些方法(比如 get_context_data)在你的子类中来提供一些新的值或者方 法。考虑一下,比如,一个仅仅需要展示一个模板的视图,about.html。Django有一个通用视图来完成这个功能 - TemplateView - 因此你可以子类化它,然后重写模板的名称:

# some_app/views.py
from django.views.generic import TemplateView
class AboutView(TemplateView):
    template_name = "about.html"

这时,你只需要添加这个新的视图到你的URLconf配置中。因为类视图本身是一个类,我 们把URL指向 as_view 这个类方法来替代类本身,这是类视图的入口点:

# urls.py
from django.conf.urls import patterns, url, include
from some_app.views import AboutView
urlpatterns = patterns('',
    (r'^about/', AboutView.as_view()),)

作为一个选择,如果你仅仅修改类视图中少量简单的属性,你可以直接传递新的属性 到类本身调用 as_view 方法中:

from django.conf.urls import patterns, url, include
from django.views.generic import TemplateView
urlpatterns = patterns('',
    (r'^about/', TemplateView.as_view(template_name="about.html")),)

一个类似的重写模式可以用在 RedirectView 的 url 属性上,这是另外一个简单的通用视图。

Minin

如果要深入理解class-based view, 那首先就要了解什么是Mixin! Django把基本的http请求和响应抽象出来, 封装成各自的类, 在使用过程中只需把各个基类聚合到一起使用, 并按照自己的要求重写自己需要的方法就可以了, 那么就把这些基类叫Mixin吧. 在Django中比较基础的Mixin主要有几类:

  1. View(视图基础类)

  2. SingleObjectMixin(单对象类)

  3. MultipleObjectMixin(多对象类)

  4. TemplateResponseMixin(模板响应类)

  5. FormMixin(表单类)

  6. YearMixin, MonthMixin, DayMixin, WeekMixin, DateMixin(几个基于时间关系的类)

其他的所有内置class-based view都是把以上几个基础类组合, 重写方法以达到预期的结果. 比如DetailView这个类就组合了SingleObjectTemplateResponseMixin和BaseDetailView.

对象的通用视图

TemplateView确实很有用,但是你可能需要把数据库中的内容查询展示出来,没关系,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 __unicode__(self):
        return self.nameclass Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField('Author')
    publisher = models.ForeignKey(Publisher)
    publication_date = models.DateField()

为了给所有的Publisher建立一个列表页,我们将按照这样的方式来配置URLconf:

from django.conf.urls import patterns, url, include
from django.views.generic import ListView
from books.models import Publisher
urlpatterns = patterns('',
    (r'^publishers/$', ListView.as_view(
        model=Publisher,template_name=’publisher_list.html‘,
    )),)

下面是简单的模板实例:

{% extends "base.html" %}
{% block content %}
    <h2>Publishers</h2>
    <ul>
        {% for publisher in object_list %}
            <li>{{ publisher.name }}</li>
        {% endfor %}
    </ul>
{% endblock %}

扩展通用视图

使用通用视图可以极大的提高开发速度。然而,在大多时候我们会发现通用视图无法满足需求。为此,我们可以对通用视图进行扩展来增加自己的功能。扩展通用视图的方法是子类化它们,并且重写它们的属性或者方法。

编写”友好的”模板

默认情况下,通用视图将所有相关Model的查询到的对象放到object_list变量中,这虽然能正常工作,但是对模板设计者不友好。

通用视图中的这个属性 : context_object_name指定上下文(context)变量要使用的名字。在这个例子中我们在URLconf中重写了它,因为这只是简单的修改:

urlpatterns = patterns('',
    (r'^publishers/$', ListView.as_view(
        model=Publisher,
        template_name=”publisher_list.html“,
        context_object_name="publisher_list",
    )),)

我们应该使用context_object_name来指定上下文(context)变量。

添加额外的上下文

我们可能需要一些通用视图没有提供的额外信息,我们可以子类化DetailView然后提供你自己的 get_context_data方法的实现。

DetailView 中默认的实现只是简单的 给模板添加了要展示的对象,但是你这可以这么重写来展示更多信息:

from django.views.generic import DetailView
from books.models import Publisher, Book
class PublisherDetailView(DetailView):
    context_object_name = "publisher"
    model = Publisher
    def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context
        context = super(PublisherDetailView, self).get_context_data(**kwargs)
        # Add in a QuerySet of all the books
        context['book_list'] = Book.objects.all()
        return context

查看对象的子集合

model参数指定了视图(view)在哪个数据库模型之上进行操作,但是这个太不灵活了,我们可以使用 queryset参数来指定一个对象列表:

from django.views.generic import DetailView
from books.models import Publisher, Book
class PublisherDetailView(DetailView):
    context_object_name = "publisher"
    queryset = Publisher.objects.all()

指明model = Publisher 等价于快速声明的queryset = Publisher.objects.all() 。然而,使用 queryset可以定义一个过滤的对象列表:

from django.views.generic import ListView
from books.models import Book
class AcmeBookListView(ListView):
    context_object_name = "book_list"
    queryset = Book.objects.filter(publisher__name="Acme Publishing")
    template_name = "books/acme_list.html"

动态URL

另一个普遍的需求是在给定的列表页面中根据URL中的关键字来过滤对象。ListView 有一个 get_queryset() 方法来供我们重写。
这里,我们有一个URLconf定义了一组供捕获的参数:

from books.views import PublisherBookListView
urlpatterns = patterns('',
    (r'^books/(\w+)/$', PublisherBookListView.as_view()),)

下一个,我们定义了 PublisherBookListView 视图:

from django.shortcuts import get_object_or_404
from django.views.generic import ListView
from books.models import Book, Publisher
class PublisherBookListView(ListView):
    context_object_name = "book_list"
    template_name = "books/books_by_publisher.html"
    def get_queryset(self):
        publisher = get_object_or_404(Publisher, name__iexact=self.args[0])
        return Book.objects.filter(publisher=publisher)

参考资料

http://django-14-tkliuxing.readthedocs.org/en/latest/topics/class-based-views.html
http://simple-is-better.com/news/643
http://simple-is-better.com/news/644

© 著作权归作者所有

共有 人打赏支持
人间四月
粉丝 2
博文 70
码字总数 30455
作品 0
朝阳
程序员
django-类视图

在Django1.3之前,通用视图是以函数的方式来实现的。基于函数的实现已经不 建议使用,建议使用这里介绍的基于类的实现方式。 基于类的通用视图(以及任何继承了Django提供的基础类的基于类的...

shaohan ⋅ 2014/02/21 ⋅ 0

Django 基于类的视图源码分析 一

基于类的视图(Class-based view)是Django 1.3引入的新的视图编写方式,用于取代以前基于函数(Function-based)方式。借助于OO和Python中方便的多重继承特性,基于类的视图可以提供更好的抽象与...

XuYuan ⋅ 2013/02/05 ⋅ 0

LET'S DJ:web.py无缝迁移到django

DO: 前提是必须要配置好django使用jinja2模版,保持与老项目模版引擎一致。 Django通用视图最基础的类是View,其他如TemplateView、RedirectView等都继承自它,具体用法参见:Django 通用视...

cwalet ⋅ 2016/04/29 ⋅ 0

逃脱Asp.Net MVC框架的枷锁,使用Razor视图引擎

更多背景参看 前传:Razor视图引擎浅析 后续: eLiteWeb框架MVC(Model-View-Command) 机制解析 为什么要这么做? 1. Asp.Net MVC 其实也不是太好 2. 我有自己的敏捷Web框架, 仍然想用Razor引擎...

予沁安 ⋅ 2012/11/26 ⋅ 33

Django搭建微信公众平台详解 一

微信公众平台官方手册:http://mp.weixin.qq.com/wiki/home/index.html Python版本:2.7.10 Django版本:1.5 开发平台:新浪SAE 前提:了解django基本创建应用的步骤。根据微信公众平台官方手...

卜星星 ⋅ 2015/12/06 ⋅ 0

django 1.8 官方文档翻译: 3-4-5 内建基于类的视图的API

内建基于类的视图的API 基于类的视图的API 参考。另请参见基于类的视图 的简介。 基础视图 通用的显示视图 通用的编辑视图 通用的日期视图 基于类的视图的Mixins 基于类的通用视图 —— 索引...

apachecn_飞龙 ⋅ 2015/08/30 ⋅ 0

android自学笔记《四》——应用程序结构分析

昨天在帖子里看到的一个分析方法,很简单,给大家分享下! 呵呵,由于我也是刚开始学习Android,还没有学到下面这些知识,这里就直接截图了。 看完他这个分析之后,我对Android程序有了一个简...

郭子 ⋅ 2012/02/03 ⋅ 1

[Python] 探讨Django的MTV模式(二)

在上一篇关于Django MTV模式的文章中,简单介绍了MTV模式的结构即概念,这篇就以一个直观的小例子说明MTV的设计理念。 Django主要有4个python文件组成(models.py , views.py , urls.py ) 和h...

长平狐 ⋅ 2013/06/03 ⋅ 0

python入门系列之(三) 初识Django

我是边看Django相关文档边整理的这篇博客,相当于学习笔记,写的有点乱,如果你已经了解Django开发,就不用看了,不过这里还是涉及到了一点Django的设计思路,对理解Django还是有些好处的,文...

疑似一僧 ⋅ 2014/03/21 ⋅ 0

Django 1.3 首个Alpha版发布

Django 1.3首个Alpha版发布!Django 是一个开放源代码的Web应用框架,由Python写成。 1.3新改进: 基于Class的视图:新增了一个框架,可以使用一个类作为视图; 日志:支持Python的 logging模...

小编辑 ⋅ 2010/11/14 ⋅ 1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

SpringCloud 微服务 (六) 服务通信 RestTemplate

壹 通信的方式主要有两种,Http 和 RPC SpringCloud使用的是Http方式通信, Dubbo的通信方式是RPC 记录学习SpringCloud的restful方式: RestTemplate (本篇)、Feign 贰 RestTemplate 类似 Http...

___大侠 ⋅ 7分钟前 ⋅ 0

React创建组件的三种方式

1.无状态函数式组建 无状态函数式组件,也就是你无法使用State,也无法使用组件的生命周期方法,这就决定了函数组件都是展示性组件,接收Props,渲染DOM,而不关注其他逻辑。 无状态函数式组...

kimyeongnam ⋅ 13分钟前 ⋅ 0

react 判断实例类型

今天在写组件的时候想通过判断内部子元素不同而在父元素上应用不同的class,于是首先要解决的就是如何判断子元素的类型。 这里附上一个讲的很全面的文章: https://www.cnblogs.com/onepixel...

球球 ⋅ 20分钟前 ⋅ 0

Centos7备份数据到百度网盘

一、关于 有时候我们需要进行数据备份,如果能自动将数据备份到百度网盘,那将会非常方便。百度网盘有较大的存储空间,而且不怕数据丢失,安全可靠。下面简单的总结一下如何使用 bypy 实现百...

zctzl ⋅ 34分钟前 ⋅ 0

开启远程SSH

SSH默认没有开启账号密码登陆,需要再配置表中修改: vim /etc/ssh/sshd_configPermitRootLogin yes #是否可以使用root账户登陆PasswordAuthentication yes #是都开启密码登陆ser...

Kefy ⋅ 37分钟前 ⋅ 0

Zookeeper3.4.11+Hadoop2.7.6+Hbase2.0.0搭建分布式集群

有段时间没更新博客了,趁着最近有点时间,来完成之前关于集群部署方面的知识。今天主要讲一讲Zookeeper+Hadoop+Hbase分布式集群的搭建,在我前几篇的集群搭建的博客中已经分别讲过了Zookeep...

海岸线的曙光 ⋅ 44分钟前 ⋅ 0

js保留两位小数方法总结

本文是小编针对js保留两位小数这个大家经常遇到的经典问题整理了在各种情况下的函数写法以及遇到问题的分析,以下是全部内容: 一、我们首先从经典的“四舍五入”算法讲起 1、四舍五入的情况...

孟飞阳 ⋅ 今天 ⋅ 0

python log

python log 处理方式 log_demo.py: 日志代码。 #! /usr/bin/env python# -*- coding: utf-8 -*-# __author__ = "Q1mi""""logging配置"""import osimport logging.config# 定义三种......

inidcard ⋅ 今天 ⋅ 0

mysql 中的信息数据库以及 shell 查询 sql

Information_schema 是 MySQL 自带的信息数据库,里面的“表”保存着服务器当前的实时信息。它提供了访问数据库元数据的方式。 什么是元数据呢?元数据是关于数据的数据,如数据库名或表名,...

blackfoxya ⋅ 今天 ⋅ 0

maven配置阿里云镜像享受飞的感觉

1.在maven目录下的conf/setting.xml中找到mirrors添加如下内容,对所有使用改maven打包的项目生效。 <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.al......

kalnkaya ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部