1. 什么情况下用通用视图

appname/views.py 中,对比 index(), detail() 和 result():

  1. from django.shortcuts import render, get_object_or_404
  2. from .models import Question
  3. # 应用首页:问题索引
  4. def index(request):
  5. latest_question_list = Question.objects.order_by('-pub_date')[:5]
  6. return render(request, 'polls/index.html', {
  7. 'latest_question_list': latest_question_list,
  8. })
  9. # 问题详情
  10. def detail(request, question_id):
  11. question = get_object_or_404(Question, id=question_id)
  12. return render(request, 'polls/detail.html', {
  13. 'question': question
  14. })
  15. # 问题结果
  16. def result(request, question_id):
  17. question = get_object_or_404(Question, id=question_id)
  18. return render(request, 'polls/results.html', {
  19. 'question': question
  20. })

会发现有共同点,即:从数据库中获取数据,有则显示,无则显示404

对于这一类操作,就可以用 通用视图

2. 怎样替换为通用视图

  1. from django.shortcuts import render, get_object_or_404
  2. from django.views import generic # 通用视图
  3. from django.utils import timezone
  4. from .models import Question
  5. class IndexView(generic.ListView):
  6. """
  7. 应用首页:问题索引
  8. """
  9. template_name = 'polls/index.html'
  10. context_object_name = 'latest_question_list'
  11. def get_queryset(self):
  12. """
  13. 返回最近五个问题(不包括未来日期问题)
  14. """
  15. return Question.objects.filter(
  16. pub_date__lte=timezone.now() # 返回比当前时间之前或者相等的内容
  17. # __gt 大于(greater than)
  18. # __gte 大于等于(equal)
  19. # __lt 小于(lesser)
  20. # __lte 小于等于
  21. ).order_by('-pub_date')[:5]
  22. class DetailView(generic.DetailView):
  23. """
  24. 问题详情
  25. """
  26. model = Question
  27. template_name = 'polls/detail.html'
  28. def get_queryset(self):
  29. """
  30. 过滤发布日期为当前时间之后的,不予显示
  31. 只显示今天以及之前的
  32. """
  33. return Question.objects.filter(pub_date__lte=timezone.now())
  34. class ResultView(generic.DetailView):
  35. """
  36. 问题结果
  37. """
  38. model = Question
  39. template_name = 'polls/results.html'

3. 通用视图必备

  1. 作用于的模型:一般用 model 属性提供,比如:model = Question
  2. get_queryset():对获取到的内容按条件进行筛选

3.1. generic.ListView 对象列表

显示一个对象列表

  1. 模板:默认是 appname/modelname_list.html,可以用 template_name 属性指定
  2. context变量:默认是 question_list,可以用 context_object_name 属性指定

3.2. generic.DetailView 特定对象详情

显示一个特定类型对象的详细信息

  1. 主键值:DetailView 期望从 URL 中获取 pk 主键值,所以需要将 URLconf 中的其他名改成 pk,比如:<int:question_id>/result/ 改为 <int:pk>/result/
  2. 模板:默认是 appname/modelname_detail.html,可以用 template_name 属性指定
  3. context变量:默认是 Django 根据模型提供的 question