Django 1.6 最佳实践: 怎样正确使用 CBVs (Class-based views)


Class-based views是Django为解决建站过程中的常见的呈现模式而建立的. 在这节中, 我们着重讲一下CBVs的使用技巧和一般原则.

1. CBVs的使用原则

  • 代码越少越好
  • 永远不要反复代码
  • View应当仅仅包括呈现逻辑, 不应包括业务逻辑
  • 保持view逻辑清晰简单
  • 不要将CBVs用作403, 404, 500的错误处理程序
  • 保持mixin简单明了

2. 怎样使用mixin

在编程中mixin是指为继承它的class提供额外的功能, 但它自身却不能单独使用的类. 在具有多继承能力的编程语言中, mixin能够为类添加额外功能或方法. 在Django中, 我们能够使用mixin为CBVs提供很多其它的扩展性, 当然在类继承过程中, 我们推荐下面原则:

  • Django自身提供的View永远在最右边
  • mixin依次在以上view的左边
  • mixin永远继承自Python的object类型

在这里顺便推荐一个非常好的django库: django-braces . 该库中提供众多django的mixin, 能够方便我们日常使用.

下面是一个简单地样例, TemplateView是django自身提供的基本View, 因此在最右边; FreshFruitMixin则在TemplateView左边; FreshFruitmixin继承自object:

from django.views.generic import TemplateView

  class FreshFruitMixin(object):

    def get_context_data(self, **kwargs):
context = super(FreshFruitMixin, self).get_context_data(**kwargs)
context["has_fresh_fruit"] = True
return context class FruitFlavorView(FreshFruitMixin, TemplateView):
template_name = "fruit_flavor.html"

3. 怎样使用Django自身的CBV

CBVs在功能上的可扩展性, 牺牲的是简单性, 一个CBV最多的时候拥有8个import关系. (假设希望进一步了解这些继承关系, 能够使用 Classy Class-Based Views 进行查看.)
所以要弄懂那个View最适合当下的场景对于开发者也是一个挑战. 为了降低CBVs的使用难度, 我们将这些View和主要的使用方法列在下表中, 为了显示方便, 名字前的django.views.generic前缀皆省去:

名字 目的 样例
View 基本View, 能够在不论什么时候使用 见后面具体介绍
RedirectView 又一次定向到其它URL 将訪问"/log-in/"的用户又一次定向到"/login/"
TemplateView 显示Django HTML template 一般站点中使用模板显示的页
ListView 显示对象列表 文章列表页
DetailView 显示对象详情 文章具体页
FormView 提交From 站点联系我们或emai订阅form
CreateView 创建对象 创建新文章页
UpdateView 更新对象 改动文章页
DeleteView 删除对象 删除文章页
Generic date views 显示一段时间内的对象 按时间归类的博客

4. CBVs的使用技巧

a. 限定訪问权限

在django tutorial中介绍了 怎样一起使用django.contrib.auth.decorators.login_required和CBV ,
这是一个典型的错误样例.

还好, 我们有django-braces. 在django-braces中已经提供了一个LoginRequiredMixin:

# myapp/views.py
from django.views.generic import DetailView from braces.views import LoginRequiredMixin from .models import Article class ArticleDetailView(LoginRequiredMixin, DetailView):
model = Article

b. 在form提交成功后运行代码

当须要在form提交成功后运行自己定义的代码时, 能够使用form_valid()方法, form_valid()方法返回的是django.http.HttpResponseRedirect:

# myapp/views.py
from django.views.generic import CreateView from braces.views import LoginRequiredMixin from .models import Article class ArticleCreateView(LoginRequiredMixin, CreateView):
model = Article
field = ('title', 'slug', 'content') def form_valid(self, form):
# 自己定义的代码逻辑写在这里
return super(ArticleCreateView, self).form_valid(form)

c. 在form提交不成功后运行代码

当须要在form提交不成功后运行自己定义的代码时, 能够使用form_invalid()方法, form_invalid()方法返回的也是django.http.HttpResponseRedirect:

# myapp/views.py
from django.views.generic import CreateView from braces.views import LoginRequiredMixin from .models import Article class ArticleCreateView(LoginRequiredMixin, CreateView):
model = Article def form_invalid(self, form):
# 自己定义的代码逻辑写在这里
return super(ArticleCreateView, self).form_invalid(form)

5. CBV和form怎样结合使用

以下我们介绍一下常见的django form和CBV结合使用的模式, 首先我们定义一个Article model方便举例:

# myapp/models.py
from django.db import models
from django.core.urlresolvers import reverse STATUS = {
(0, 'zero'),
(1, 'one'),
} class Article(models.Model):
title = model.CharField(max_length=255)
slug = model.SlugField()
review_num = models.IntegerField(default=0, choices=STATUS) def get_absolute_url(self):
return reverse("article_detail", kwargs={"slug": self.slug})

a. Views和ModelForm

以下的样例中, 我们利用django.contrib.messages和CBVs构建一套创建, 更新和显示一篇article的view, 包含:

  • ArticleCreateView: 用于创建新article
  • ArticleUpdateView: 用于更新article
  • ArticleDetailView: 用于确认创建或更新后的article
# myapp/views.py
from django.contrib import messages
from django.views.generic import CreateView, UpdateView, DetailView from braces.views import LoginRequiredMixin from .models import Article class ArticleActionMixin(object):
@property
def success_msg(self):
return NotImplemented def form_valid(self, form):
messages.info(self.request, self.success_msg)
return super(ArticleActionMixin, self).form_valid(form) class ArticleCreateView(LoginRequiredMixin, ArticleActionMixin, CreateView):
model = Article
field = ('title', 'slug', 'review_num')
success_msg = "Article Created!" class ArticleUpdateView(LoginRequiredMixin, ArticleActionMixin, UpdateView):
model = Article
field = ('title', 'slug', 'review_num')
success_msg = "Article Updated!" class ArticleDetailView(DetailView):
model = Article

接下来是template

{# templates/myapp/article_detail.html #}
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li>{ message } </li>
</ul>
{% endif %}

b. Views和Form

以下我们以搜索article功能为样例, 介绍一下CBV和form的常见使用样式, 在article列表页中点击搜索button, 显示搜友符合条件的article列表:

# myapp/views.py
from django.views.generic import ListView from .models import Article class ArticleListView(ListView):
model = Article def get_queryset(self):
queryset = super(ArticleListView, self).get_queryset() q = self.request.GET.get('q') if q:
return queryset.filter(title__icontains=q) return queryset

然后能够使用include下面tenplate呈现搜索form:

{# templates/myapp/_article_search.html #}
<form action="{% url "article_list" %} method="GET"">
<input type="text" name="q"></>
<button type="submit">搜索</>
</form>

6. 单独使用View

仅仅用django.views.generic.View, 而不用FBV来构建全部django项目中的view也是可行的, 这也没有你所想象的那么复杂. 使用View的优点是, 我们不须要写很多内套式的if语句, 我们能够直接覆盖使用View的get(), post()等方法:

from django.shortcuts import get_object_or_404, render, redirect
from django.views.generic import View from braces.views import LoginRequiredMixin from .forms import ArticleForm
from .models import Article class ArticleView(LoginRequiredMixin, View): def get(self, request, *args, **kwargs):
article = get_object_or_404(Article, pl=kwargs['slug'])
return render(request,
"myapp/article_detail.html",
{"article": article}
) def post(sele, request, *args, **kwargs):
article = get_object_or_404(Article, pl=kwargs['slug'])
form = ArticleForm(request.POST)
if form.is_valid():
form.save()
return redirect("myapp:article", article.slug)

Django 1.6 CBVs的更多相关文章

  1. django form使用学习记录

    Django forms使用容易, 又方便扩展, 因此Django admin和CBVs基本都基于forms使用. 事实上, 由于django forms的强大验证功能, 大多数Django API ...

  2. django学习总结

    tips:django官方中文文档(http://python.usyiyi.cn/django/index.html),django基础教程(http://www.ziqiangxuetang.co ...

  3. Django笔记&教程 7-3 拓展CBVs(Class-based views)

    Django 自学笔记兼学习教程第7章第3节--拓展CBVs(Class-based views) 点击查看教程总目录 一般而言,直接使用原生的Class-based views,能展现的样式和内容是 ...

  4. 因为中国队赢了,再撸一下DJANGO的官方文档吧

    对比一下,CBVS和FBVS,哪个方便? from django.shortcuts import render from django.http import Http404 from django ...

  5. Django自身的CBV列表

    慢慢就有感觉了.... 这个是可以快速开发很多东东,不过,类视图要求的积累还是有一些的.. ~~~~~~~~~~~~~ CBVs在功能上的可扩展性, 牺牲的是简单性, 一个CBV最多的时候拥有8个im ...

  6. Django学习笔记之Class-Based-View

    Django写的多了,有些问题才逐渐认识到. 比如有一个view比较复杂,调用了很多其他的函数.想要把这些函数封装起来,怎么办? 当然,可以用注释#------view------这样将函数隔离开,这 ...

  7. Django笔记&教程 总目录

    本篇博客只有目录,正文内容在目录章节链接的博客里 除目录本身外,没有链接的章节,说明内容还没开始编辑 本项目笔记仍在不断创作中,还有些内容会根据自身所学不断更新完善 本项目主要为markdwon文档, ...

  8. Django笔记&教程 7-1 基于类的视图(Class-based views)介绍

    Django 自学笔记兼学习教程第7章第1节--基于类的视图(Class-based views)介绍 点击查看教程总目录 1 介绍 Class-based views (CBVs) are view ...

  9. Django 小实例S1 简易学生选课管理系统 11 学生课程业务实现

    Django 小实例S1 简易学生选课管理系统 第11节--学生课程业务实现 点击查看教程总目录 作者自我介绍:b站小UP主,时常直播编程+红警三,python1对1辅导老师. 课程模块中,学生需要拥 ...

随机推荐

  1. C语言练习代码

    1.运用for循环根据输入的金字塔层数,输出金字塔 eg: #include <stdio.h>int main(void){ int i,j,num; printf("请输入三 ...

  2. redhat Enterprise Linux Server release 7.2(Maipo) 安装redis-stat

    项目需要在rh7.2安装redis-stat,各种编译不过.通过一步步跟踪编译错误日志发现时缺少各种开发库. 需要安装的库列表如下: zlib-devel openssl-devel readline ...

  3. 我的格斗梦——张龙海(R.J)谈游戏动画师职业(转)

    编者按:他是一个生在东北,祖藉却是韩国的年轻人.从小生性好动的他觉得上课 学习十分枯燥,所以高中没毕业便辍学在家.但他仍是一个喜欢动漫.游戏的年轻人,因为热爱所以他用父母给的钱开始了求学之路,在之后的 ...

  4. nagios高可用性设置

    1. 前言 如何来实现nagios监控系统的高可用,监控是很重要的,在关键时刻进行通知报警,通知人员进行相应的处理. 在进行配置的时候,需要配置两台相同服务的nagios服务器,配置相同,同时在运行, ...

  5. Chapter12&Chapter13:程序实例

    文本查询程序 要求:程序允许用户在一个给定文件中查询单词.查询结果是单词在文件中出现的次数及所在行的列表.如果一个单词在一行中出现多次,此行只列出一次. 对要求的分析: 1.读入文件,必须记住单词出现 ...

  6. [转]Javascript定义类的三种方法

    作者: 阮一峰 原文地址:http://www.ruanyifeng.com/blog/2012/07/three_ways_to_define_a_javascript_class.html 将近2 ...

  7. Android中使用logwrapper来重定向应用程序的标准输出

    在Android应用程序调试中,有时候第三方应用程序的日志输出是通过printf之类的标准函数输出的,logcat不能捕获这些日志,一个方法是使用logwrapper命令来执行第三方应用程序,logw ...

  8. Application_Error

    //出现未捕捉的异常时,系统调用本方法,一般用于记录日志.错误页的重定向一般在web.config中设置.        protected void Application_Error(object ...

  9. Fast-paced Multiplayer

    http://www.gabrielgambetta.com/fpm1.html —————————————————————————————————————————————————————— Fast ...

  10. hibernate里createSQLQuery的addEntity()和setResultTransformer()方法

    http://langgufu.iteye.com/blog/1565397 ————————————————————————————————————————————————————————————— ...