Django教程④(模板)

首先

在Django教程第3部分(创建模型、Django管理员)之后,尝试创建一个应用程序。在第一次创建Django应用程序时,参考《实用Django教程(基础篇)》,第3节。 (*请注意,在本文的后半部分中出现的视图图像取决于第二部分的“尝试玩API”,只有创建了名为“What’s up?”的问题以及与之关联的“Not much”和“The sky”选项,才会显示该图像。)

這是電腦轉換器的日文寫法。

按照教程的指示,在polls/views.py文件中添加一个视图函数,并在polls/urls.py中注册与该视图函数相关联的URLconf。

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)
from django.urls import path

from . import views

app_name = 'polls'
urlpatterns = [
    path('', views.index, name='index'),
    path('<int:question_id>/', views.detail, name='detail'),
    path('<int:question_id>/results/', views.results, name='results'),
    path('<int:question_id>/vote/', views.vote, name='vote'),
]

重要的是在urls.py中所写的”。使用<>可以将URL的一部分作为关键字变量传递给视图函数。例如,如果有一个请求”/polls/34/”,detail函数将以question_id参数接收34。这是一种路径转换器的语法,Django提供了5种转换器:”int,str,path,slug,uuid”,也可以自定义转换器。

DTL(Django模板语言)

Django使用了一个名为DTL的模板系统,可以实现变量显示、过滤器、模板标签等功能。关于有哪些内容的详细信息,请参阅官方文档。
到目前为止,我们处理的视图函数在编码中也涉及了设计部分(虽然这里的设计只是将字符串排列起来)。因此,如果要更改页面设计,就必须编辑Python代码。因此,可以使用DTL将设计与Python代码分离。

首先,要设置config/settings.py中的TEMPLATES。只需要修改DIRS设置即可,其余设置保持默认不变。

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
    • BACKEND : テンプレートエンジンを設定する。デフォルト以外にも Jinja2 などを設定できるらしい。Jinja2 の方が機能が豊富ということも聞いたが、ここは一旦デフォルトのままで Django に慣れてきたら試したい。

 

    • DIRS : どのディレクトリを優先してテンプレートを探しに行くかという順番を指定する。デフォルトでは [(空白)] だが、ここでは上記のように [os.path.join(BASE_DIR, ‘templates’)] としておく。(import os を忘れずに。)設定を変えた理由は後述。

 

    • APP_DIRS : テンプレートを探す際に各アプリケーションディレクトリ直下の templates ディレクトリを優先的に探しにいくかどうかを設定する。デフォルトでは True 。

 

    OPTIONS : 正直あんまりよくわからない。わかる人教えてください。上記コードはデフォルトのまま。

在这里解释更改 DIRS 设置的原因。在教程中,创建了名为 polls/templates/polls 的目录,并在其中创建了模板 index.html,保持了默认设置。这种结构显然不清晰,而且根据以下教程中的原因,不需要在 polls/templates 目录下创建 polls 子目录才是适当的。

创建模板的命名空间

您可能会想,为什么不直接将自己创建的模板放在polls/templates中,而不是创建另一个名为polls的子目录呢。但是,实际上这是一个不好的想法。Django会使用与名称匹配的第一个模板,所以如果不同的应用程序中有相同名称的模板,Django将无法区分它们。因此,您需要告诉Django正确的模板,而最简单的方法就是为它们提供命名空间。通过将模板放在另一个具有相同名称的目录中,与应用程序相同的名称,这就是这么做的原因。

为了使目录结构更加清晰易懂,我们在基本目录下创建了一个templates目录,并将每个应用程序的模板作为其子目录处理。以下是实际的结构示例:

为了使目录结构更加清晰易懂,我们在基本目录下创建了一个templates目录,并将每个应用程序的模板作为其子目录处理。以下是实际的结构示例:

mysite       (<- ベースディレクトリ)
|-- manage.py
|-- config   (<- 設定ディレクトリ)
|   |-- __init__.py
|   |-- asgi.py
|   |-- settings.py
|   |-- urls.py
|   `-- wsgi.py
|-- polls    (<- アプリケーション)
|   |-- __init__.py
|   |-- admin.py
|   |-- apps.py
|   |-- migrations
|   |   `-- __init__.py
|   |-- models.py
|   |-- tests.py
|   `-- views.py
`-- templates (<- テンプレート)
    `-- polls
        `-- index.html

通过这样的配置,我们可以清晰明了地从基础目录中统一管理每个应用程序的模板。出于这个原因,我们改变了DIRS的设置。你可能会问:”如果采用这个配置,APP_DIRS应该不应该设置为False,优先搜索每个应用程序目录下的templates吗?” 然而,如果这样设置,可能会导致找不到管理网站的模板等问题,所以我们仍然将其设置为True。(如果想尝试,请在开发服务器上将 ‘APP_DIRS’ 设置为False,然后访问 http://localhost:8000/admin/,您将会看到错误信息。)

顺便提一下,有关 admin 的模板可以在 django/contrib/admin/templates/admin 目录下找到。要知道 django 源文件的位置,可以使用 $ python -c “import django; print(django.__path__)” 命令。

创建模板

在创建模板之前,需要修改polls/views.py文件中的index函数以显示模板。

from django.shortcuts import render

from .models import Question


def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    context = {'latest_question_list': latest_question_list}
    return render(request, 'polls/index.html', context)

render()函数接受三个参数:第一个参数是请求对象,第二个参数是模板名称,第三个参数(可选)是以字典形式指定的上下文。它将使用指定上下文渲染模板,并返回该HttpResponse对象。

在templates/polls文件夹的根目录下创建一个名为index.html的文件,并编写以下代码。代码中的latest_question_list是在polls/views.py中指定的上下文键的名称,它表示与该键对应的变量。

{% if latest_question_list %}
    <ul>
    {% for question in latest_question_list %}
        <li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}

以上的代码是用DTL语法编写的。用{% %}括起来的部分是模板标签,提供了方便的模板标签,如{% if (条件分支) %}或{% for (循环) %}等。在这里,如果latest_question_list存在,则以列表形式显示与其数量相对应的内容,如果不存在,则显示”No polls are available.”。此外,a标签内的href可以硬编码为

这样的链接部分,但由于URL的更改会变得混乱,因此在这里使用了{% url %}这个模板标签。这个模板标签可以通过在polls.urls.py中使用path()函数定义的URL进行反向解析。以下是本文开头提到的polls/urls.py的内容。

from django.urls import path

from . import views

app_name = 'polls'
urlpatterns = [
    path('', views.index, name='index'),
    path('<int:question_id>/', views.detail, name='detail'),
    path('<int:question_id>/results/', views.results, name='results'),
    path('<int:question_id>/vote/', views.vote, name='vote'),
]

{% url %} 的第一个参数是 URL 的模式名([app_name]:[path_name]),第二个参数及之后用于指定值以匹配该模式,如果正则表达式组包含在模式中。换句话说,对于

这种情况,它引用了在上述 polls/urls.py 文件中注册的 detail 路径的 ‘/’。这样一来,如果要更改 URL 模式,只需更改 polls/urls.py 文件,而无需更改模板。尽管可以不使用 app_name 来引用,但当应用程序变得复杂时,最好通过 app_name 来定义命名空间,以便在存在同名视图的情况下不会出现问题。

index.png

404错误

除了返回与请求对应的 HttpResponse 对象,视图还承担着返回异常的角色。在这里,我们将在显示指定投票问题的 detail 视图中实现异常处理。请将以下代码添加到 polls/views.py 中。

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})

若要使该细节视图可用,需要创建polls/detail.html并写入以下代码。get_object_or_404()函数执行get(),如果对象不存在,则引发Http404错误。

<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
detail.png
error.png

最后

多亏了实用的《Django实战教程(基础篇)》,我的理解有所提升。这本书很好。接下来,我会继续进行《初识Django应用开发》的第4章。

以下是相关文章的链接:
– Django教程①(安装和创建项目)
– Django教程②(创建视图)
– Django教程③(创建模型和使用Django Admin)
– Django教程⑤(通用视图)
– Django教程⑥(自动测试)
– Django教程⑦(静态文件)

广告
将在 10 秒后关闭
bannerAds