[part 3] 第一个 Django 应用

本节聚焦视图,django 中的视图更类似于其他框架的控制器,侧重于数据渲染

概述

  • 框架 view 是 web 页的一种"类型",它通常由指定函数和模板组成
  • 本 poll 应用由 index,detail,results三个展示页,一个 vote动作组成
  • Django视图表现为单一的可调用对象(函数,或视图类方法),选择视图由来自请求的 url 决定,即 URLconfs

Request

  1. 通常 ROOT URLCONF 决定, 但若请求HttpRequest 对象存在 urlconf(被中间件添加)属性,它的值会放在根urls配置
  2. 框架加载模块会在 urlpatterns 变量上查找,它 django.urls.path() 或 django.urls.re_path()实例上的序列
  3. 框架依次找到了第一个匹配的 URL 正则,会立即终止,不会采用后续符合规则的路由
  4. 一旦匹配,Django 则导入并调用给定的视图,视图接收以下参数
    • HttpRequest 实例
    • 传递关键参建将覆盖在 django.urls.path() 或 django.urls.re_path()内的可选关键字
  5. 无匹配,将抛异常框架会回调相应的错误句柄视图

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>

进入 Part 4 学习

源码

第一个Django应用程序

本作品采用《CC 协议》,转载必须注明作者和本文链接
pardon110
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
开发者 @ 社科大
文章
134
粉丝
24
喜欢
101
收藏
55
排名:106
访问:8.9 万
私信
所有博文
社区赞助商