对Django中通用视图generic的一些理解

在django中,多种相似的view视图会造成代码的冗余。这时候,可以用django中的通用视图来解决这个问题。

例如:

# polls/urls
from django.urls import path

from . import views

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

# polls/views
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)

def detail(request, question_id):
	question = get_object_or_404(Question, pk=question_id)
	return render(request, 'polls/detail.html', {'question': question})

def results(request, question_id):
	question = get_object_or_404(Question, pk = question_id)
	return render(request, 'polls/results.html',{'question': question})

这种视图有很多相似的地方。
其实,这类视图都有一个共通的地方,从根据url提供的参数从数据库中获取数据,加载模板文件并且返回渲染后的模板。django中的通用视图可以解决这个问题。

先来看看用generic修改后的样子:

# polls/urls
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'),
]

# polls/views
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

# 使用Listview
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]

# 使用DetailView
class DetailView(generic.DetailView):
    model = Question
    template_name = 'polls/detail.html'


class ResultsView(generic.DetailView):
    model = Question
    template_name = 'polls/results.html'

两个通用视图的区别:
ListView显示一个对象列表。
DetailView显示一个特定类型对象的详细信息页面。

下面解释以下更改的内容:

1、由于DetailView需要从url中获取主键值,所以在urls中将question_id更改为pk(主键值);
2、在默认情况下,通用视图 DetailView 使用一个叫做 < app name>/< model name>_detail.html 的模板。在例子中,它将使用 “polls/Question_detail.html” 模板。template_name 属性是用来告诉 Django 使用一个指定的模板名字,而不是自动生成的默认名字。类似地,ListView 使用一个叫做 < app name>/< model name>_list.html 的默认模板;使用 template_name 来告诉 ListView 使用已经存在的 “polls/index.html” 模板。

修改中遇到的问题

1、

TypeError: __init__() takes 1 positional argument but 2 were given

解决方法:没有添加as_view()方法(自动查找指定方法)

修改前:

path('', views.IndexView, name='index'),

修改后:

path('', views.IndexView.as_view(), name='index'),

2、

Generic detail view ResultsView must be called with either an object pk or a slug.

没有修改question_id 为pk 因为通用视图DetailView已经制订了model 所以需要提供pk(主键值)。

修改前:

path('<int:question_id>/results/', views.ResultsView.as_view(), name='results'),

修改后:

path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值