[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 协议》,转载必须注明作者和本文链接