Django基于类的视图(views)


一个视图(view)是一个可调用对象(callable), 不仅仅局限于一个函数。
https://docs.djangoproject.com/en/1.8/ref/class-based-views/

== 介绍

基于类的视图(class-based views)相比较于基于函数的视图(function-based views)的不同和优点:
* 处理不同HTTP方法(GET,POST,etc)的代码可以定位到不同的函数,而不是使用不同条件分支。
* 如mixin(多重继承)的面相对象技术,可以用于将代码组织成可以复用的模块。

- 使用基于类的视图(view)

from django.http import HttpResponse
from django.views.generic import View
class MyView(View):
    def get(self, request):
        # <view logic>
        return HttpResponse('result')

在基于类的方法中,你没有必要使返回与基于函数的方法保持一致,即返回某种形式的HttpResponse.
意味着http shortcuts和TemplateResponse对象在基于类的方法中可用。

有两种方法设置类的属性:
class MorningGreetingView(GreetingView):
    greeting = "Morning to ya"

urlpatterns = [
    url(r'^about/', GreetingView.as_view(greeting="G'day")),
]

- 使用Mixins
Mixins是一种形式的多重继承,多个父类的行为和方法可以被组合。

- 处理forms
from .forms import MyForm
class MyFormView(View):
    form_class = MyForm
    initial = {'key': 'value'}
    template_name = 'form_template.html'

    def get(self, request, *args, **kwargs):
        form = self.form_class(initial=self.initial)
        return render(request, self.template_name, {'form': form})

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        if form.is_valid():
            # <process form cleaned data>
            return HttpResponseRedirect('/success/')

        return render(request, self.template_name, {'form': form})

- 修饰符
from django.contrib.auth.decorators import login_required, permission_required
from django.views.generic import TemplateView
from .views import VoteView
urlpatterns = [
    url(r'^about/', login_required(TemplateView.as_view(template_name="secret.html"))),
    url(r'^vote/', permission_required('polls.can_vote')(VoteView.as_view())),
]

class ProtectedView(TemplateView):
    template_name = 'secret.html'

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(ProtectedView, self).dispatch(*args, **kwargs)


== 内建的基于类的通用显示视图(generic views)
* 为单个对象显示列表和详情页面
* 为基于日期的对象按year/month/day显示归档页面,及详情、最近页面。
* 允许用户create,update,delete对象 - 在认证或未认证情况下。

- 扩展通用视图
推荐通过继承子类和override属性及方法来扩展generic views,而不是在URLCong中传入大量配置。

- 通用视图对象
# models.py
from django.db import models
class Publisher(models.Model):
只需添加下列代码:
# views.py
class PublisherList(ListView):
    model = Publisher  # queryset = Publisher.objects.all()
# urls.py
urlpatterns = [
    url(r'^publishers/$', PublisherList.as_view()),
]
当然,还需要写一个模板(template). 
我们可以显示的通过添加template_name属性指明template路径,
如果不显示指定,Django根据对象名使用默认路径"books/publisher_list.html"
# 渲染时context包含一个object_list变量包含所有对象,及publisher_list
{% extends "base.html" %}
{% block content %}
    <h2>Publishers</h2>
    <ul>
        {% for publisher in object_list %}
            <li>{{ publisher.name }}</li>
        {% endfor %}
    </ul>
{% endblock %}
# context_object_name
class PublisherList(ListView):
    model = Publisher
    context_object_name = 'my_favorite_publishers'

- 在context中添加其他信息
class PublisherDetail(DetailView):
    model = Publisher
    def get_context_data(self, **kwargs):
        # 获取context
        context = super(PublisherDetail, self).get_context_data(**kwargs)
        # 添加QuerySet of all the books
        context['book_list'] = Book.objects.all()
        return context

- 只显示列表子集
class PublisherDetail(DetailView):
    context_object_name = 'publisher'
    queryset = Publisher.objects.all()[:10]

class BookList(ListView):
    queryset = Book.objects.order_by('-publication_date')
    context_object_name = 'book_list'

- 动态过滤
urlpatterns = [
    url(r'^books/([\w-]+)/$', PublisherBookList.as_view()),
]

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)

def get_context_data(self, **kwargs):
context = super(PublisherBookList, self).get_context_data(**kwargs)
context['publisher'] = self.publisher
return context

- 其他用法
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


== 内建的基于类的通用编辑视图 (Forms)


== 在基于类的视图中使用Mixins

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值