1. 什么情况下用通用视图
appname/views.py
中,对比 index(), detail() 和 result():
from django.shortcuts import render, get_object_or_404
from .models import Question
# 应用首页:问题索引
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
return render(request, 'polls/index.html', {
'latest_question_list': latest_question_list,
})
# 问题详情
def detail(request, question_id):
question = get_object_or_404(Question, id=question_id)
return render(request, 'polls/detail.html', {
'question': question
})
# 问题结果
def result(request, question_id):
question = get_object_or_404(Question, id=question_id)
return render(request, 'polls/results.html', {
'question': question
})
会发现有共同点,即:从数据库中获取数据,有则显示,无则显示404
对于这一类操作,就可以用 通用视图
2. 怎样替换为通用视图
from django.shortcuts import render, get_object_or_404
from django.views import generic # 通用视图
from django.utils import timezone
from .models import Question
class IndexView(generic.ListView):
"""
应用首页:问题索引
"""
template_name = 'polls/index.html'
context_object_name = 'latest_question_list'
def get_queryset(self):
"""
返回最近五个问题(不包括未来日期问题)
"""
return Question.objects.filter(
pub_date__lte=timezone.now() # 返回比当前时间之前或者相等的内容
# __gt 大于(greater than)
# __gte 大于等于(equal)
# __lt 小于(lesser)
# __lte 小于等于
).order_by('-pub_date')[:5]
class DetailView(generic.DetailView):
"""
问题详情
"""
model = Question
template_name = 'polls/detail.html'
def get_queryset(self):
"""
过滤发布日期为当前时间之后的,不予显示
只显示今天以及之前的
"""
return Question.objects.filter(pub_date__lte=timezone.now())
class ResultView(generic.DetailView):
"""
问题结果
"""
model = Question
template_name = 'polls/results.html'
3. 通用视图必备
- 作用于的模型:一般用 model 属性提供,比如:model = Question
- get_queryset():对获取到的内容按条件进行筛选
3.1. generic.ListView 对象列表
显示一个对象列表
- 模板:默认是
appname/modelname_list.html
,可以用template_name
属性指定 - context变量:默认是 question_list,可以用
context_object_name
属性指定
3.2. generic.DetailView 特定对象详情
显示一个特定类型对象的详细信息
- 主键值:DetailView 期望从 URL 中获取 pk 主键值,所以需要将 URLconf 中的其他名改成 pk,比如:
<int:question_id>/result/
改为<int:pk>/result/
- 模板:默认是
appname/modelname_detail.html
,可以用template_name
属性指定 - context变量:默认是 Django 根据模型提供的 question