[part 3] 第一个 Django 应用
本节聚焦视图,django 中的视图更类似于其他框架的控制器,侧重于数据渲染
概述
- 框架
view是web页的一种"类型",它通常由指定函数和模板组成 - 本
poll应用由index,detail,results三个展示页,一个vote动作组成 Django视图表现为单一的可调用对象(函数,或视图类方法),选择视图由来自请求的url决定,即URLconfs
Request
- 通常
ROOT URLCONF决定, 但若请求HttpRequest对象存在urlconf(被中间件添加)属性,它的值会放在根urls配置 - 框架加载模块会在
urlpatterns变量上查找,它django.urls.path()或django.urls.re_path()实例上的序列 - 框架依次找到了第一个匹配的
URL正则,会立即终止,不会采用后续符合规则的路由 - 一旦匹配,Django 则导入并调用给定的视图,视图接收以下参数
HttpRequest实例- 传递关键参建将覆盖在
django.urls.path() 或 django.urls.re_path()内的可选关键字
- 无匹配,将抛异常框架会回调相应的错误句柄视图
Django中的
urlconf更类似于其他框架中的路由器,ROOT_URLCONF-->urlpatterns
视图
<int:question_id>类似正则中的命名子模式概念,<int:是一个转换器,将匹配到路径转化为int型
#polls/views.py
def detail(request, question_id):
return HttpResponse("You're looking at question %s." % question_id)
def results(request, question_id):
response = "You're looking at the results of question %s."
return HttpResponse(response % question_id)
def vote(request, question_id):
return HttpResponse("You're voting on question %s." % question_id)
#polls/urls.py
from django.urls import path
from . import views
urlpatterns = [
# ex: /polls/
path('', views.index, name='index'),
# ex: /polls/5/
path('<int:question_id>/', views.detail, name='detail'),
# ex: /polls/5/results/
path('<int:question_id>/results/', views.results, name='results'),
# ex: /polls/5/vote/
path('<int:question_id>/vote/', views.vote, name='vote'),
]
- 每个
view对请求响应HttpResponse对象,或者诸如Http404这样的异常 - 项目
TEMPLATES配置,框架优先从INSTALLED_APPS下的默认tempaltes子目录寻找
快捷函数
django.shortcuts: render()- 隐式使用了模板加载器
- 包装返回一个
HttpResponse对象 - 不再显式的导入
loader和HttpResponse - 原型
def render(request, template_name, context=None, content_type=None, status=None, using=None)
django.shortcuts:get_object_or_404()
from django.http import Http404
from django.shortcuts import render
from .models import Question
# ...
def detail(request, question_id):
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404("Question does not exist")
return render(request, 'polls/detail.html', {'question': question})
将模型的
get()与Http404合二为一, 下面的代码与上述等价
from django.shortcuts import get_object_or_404, render
from .models import Question
# ...
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
get_list_or_404()亦类似
模板系统
- 属性访问使用
.语法, 输出{{ }} - 方法调用通常使用表达式模板标志如
{% for %} - 移除模板中的
URL硬编码,使用{% url %}实际指向polls.urls模块
# 硬编码
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
# 动态url, 参数detail引用自配置 path()中的name,相当于命名路由
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
命名url
- 框架通过在应用的 URLconf 配置中,增加
app_name设置命名空间,以其区分在不同应用中的相同url命名 - 带有应用命名空间
url名称,在模板中的应用如下
# polls/templates/polls/index.html¶
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
源码
本作品采用《CC 协议》,转载必须注明作者和本文链接
关于 LearnKu