django框架从零开始_009_通用页面

本文介绍如何使用Django的Generic Views简化应用开发流程。通过实例演示了如何将原有的视图函数转换为基于类的视图,包括ListView和DetailView,并解释了它们的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考:https://docs.djangoproject.com/en/1.9/intro/tutorial04/#use-generic-views-less-code-is-better


我们做的detail、result、index的界面非常简单,但是同时,也很冗余。这些页面做了标准网页开发应该做的事情:根据url从数据库中读取数据、加载模版页并显示出来。这种应用太常见了,所以django提供了一个快捷的"Generic Views"系统。它抽取出来的最简练的模式,你可以不用写什么view而就可以创建你的app。

下面让我们来把我们的polls系统利用generic views改写一下。我们需要做如下几步:

  1. 改写URLConf
  2. 删除不用的views
  3. 引入新的页面
首先修改polls/urls.py:
urlpatterns = [
    url(r'^$', views.IndexView.as_view(), name='index'),
    url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
    url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]

和原来相比,我们引入了IndexView.as_view()内容,以及把<question_id>改成了<pk>。

下面我们去修改相对应的views。我们把我们老的index、detail、results页面用generic views替换。polls/views.py修改为:

from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from .models import Question, Choice
from django.core.urlresolvers import reverse
from django.views import generic

class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_question_list'
    
    def get_queryset(self):
        ''' return the last five published questions.'''
        return Question.objects.order_by('-pub_date')[:5]
    
class DetailView(generic.DetailView):
    model = Question
    template_name = 'polls/detail.html'

class ResultsView(generic.DetailView):
    model = Question
    template_name = 'polls/results.html'
    
    
def vote(request, question_id):
    #return HttpResponse("You're voting on question %s." % question_id)
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the question voting form.
        return render(request, 'polls/detail.html', {'question':question, 'error_message':'You did not select a choice'})
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
        

在这里,我们引入了两个generic views:ListViewDetailView。这两种view分别实现了“显示对象列表”以及“显示对象详细属性”的功能。
  • 每一个generic view都需要知道它对应的对象类型是什么,用model属性赋值
  • DetailView需要知道对象的pk(从url传入),这也是我们把question_id改成pk的原因
DetailView默认会使用<app name>/<model name>_detail.html页面。如果需要手动设置,则修改template_name属性的值。例如我们分别制定了DetailView和ResultsView的模版名,使得他们虽然类型和model都相同,但是指向的页面不同。
类似的,ListView使用默认模版<app name>/<model name>_list.html,修改的时候同样改变template_name值。

在之前的步骤中,我们都给context变量赋值了我们需要传入的变量(question、latest_question_list之类)。在使用DetailView时,因为我们已经使用了django的model(Question),所以context名称会由django自动设置;而对于ListView,自动生成的context内容会是question_list,如果我们想修改他,那么就覆盖context_object_name属性值为我们想要的变量。当然,你也可以修改你的页面来适应django的默认值,但是显然指定context_object_name会更简单。

就是这些了,去你的server上尝试一下吧~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值