Djangle利用通用视图简化代码

当一些视图函数存在大量相似代码或功能时,可以考虑使用Djangle自带的通用视图。衔接上一篇 为Django app创建视图(下)

通用视图

泛型视图将通用模式抽象到甚至不需要编写Python代码就可以编写应用程序的程度。
一般有如下步骤:

  1. 转换URLconf。

  2. 删除一些旧的、不需要的视图。

  3. 在Django的通用视图的基础上引入新视图。

转换URLconf

打开文件 polls/urls.py,做如下修改:

from django.urls import path

from . import views

app_name = 'polls'
urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
    path('<int:pk>/', views.DetailView.as_view(), name='detail'),
    path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
    path('<int:question_id>/vote/', views.vote, name='vote'),
]

这里做的主要修改,是将第二和第三个path()里的<int:question_id>改成了<int:pk>

修改视图函数

修改polls/views.py如下:

from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic

from .models import Choice, Question


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):
    ... # 不变

我们在这里使用两个通用视图:ListView和DetailView。这两个视图分别抽象了“显示对象列表”和“显示特定类型对象的详细页”的概念。

每个视图函数都需要知道它们作用在哪个视图上,通过model属性来设置。

DetailView通用视图获取的主键名为pk,所以将<int:question_id>改成了<int:pk>

默认情况下,DeatilView通用视图使用的模板命名规则为
< app name>/< model name>_detail.html
所以在本例中,使用polls/question_detail.html。

template_name用于告诉视图函数指定模板的名称

在早前的index()视图函数中,代码如下:

def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    context = {
        'latest_question_list': latest_question_list,
    }
    return render(request, 'polls/index.html', context)

更改后的index()视图函数:

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]

这里很重要的变化是重写了get_queryset()方法以及context_object_name = ‘latest_question_list’,因为通用视图本身会自动生成返回对象的名字,比如会自动生成question_list,这样html里因为名字问题可能会获取不到返回值。所以如果想覆盖掉这个名字,就用这句话,赋值即为html里接收到的对象的名字。如果不加这句话,就需要去到html里将变量名称改为question_list。

总结

通用视图的好处就是使代码更加的简洁,需要注意的就是在使用过程中,需要通过model和template_name来指定模型和模板,另外,如果需要特定查询,需要重写get_queryset()方法。通用函数适合从项目刚开始时就考虑好哪里适合采用,以此来简化开发。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值