English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Быстрый старт Django - представления

A view is a web 'type' in a Django application, providing specific functionality and having specific templates. For example, in a blog application, there may be the following views:

Blog home page - display the last few articles. Enter the 'detail' page - permanent link page for a single item. Archive page - display all entries for all months of a given year. Monthly archive page - display all items for all days of a given month. Daily archive page - display all entries for a specific day. Comment operation - handle publishing comments for a given input.

In our poll application, there are the following four views:

The 'index' page of the issue - display the last few issues. The 'detail' page of the issue - display the text of an issue without results but with a form to vote. The 'results' page of the issue - display the results of a specific issue. Voting operation - handle voting on a specific issue to make a specific choice.

In Django, web pages and other content are provided by views. Each view is represented by a simple Python function (or method, based on a class view). Django selects a view by examining the majority of the public's favored URL (more precisely, the part of the URL after the domain).

A URL pattern is a general form of a simple URL - for example: /newsarchive/<year>/<month>/.

Write more views

Now, let's add some views in polls/views.py. These views are a bit different because they need a parameter:

def detail(request, question_id):
    return HttpResponse("You're looking at question %s." % question_id)
def results(request, question_id):
    response = "Вы смотрите результаты вопроса %s."
    return HttpResponse(response % question_id)
def vote(request, question_id):
    return HttpResponse("Вы голосуете за вопрос %s." % question_id)

Эти новые представления добавляются в модуль polls.urls в следующий вызов url(), код в файле polls/urls.py выглядит следующим образом:

from django.conf.urls import url
from . import views
urlpatterns = [
 # Пример: /polls/
    url(r'^$', views.index, name='index'),
 # Пример: /polls/5/
    url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
 # Пример: /polls/5/results/
    url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
 # Пример: /polls/5/vote/
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]

Вы можете открыть «/polls/34/» в браузере. Это вызовет метод detail() и отобразит любое предоставленное содержимое URL. Попробуйте повторно访问 «/polls/34/results/» и «/polls/34/vote/» — это покажет временные результаты и страницу голосования.

include() легко включает плагины и адреса. Поскольку polls находится в своих собственных конфигурациях URL (polls/urls.py), они могут быть расположены в «/polls/», или «/fun_polls/», или «/content/polls/», или в корне любого другого пути, и приложение все еще будет работать.

Ниже показано, что происходит, если пользователь вводит «/polls/34/» в этой системе:

Django находит соответствие '^polls/' Затем Django удаляет соответствующий текст («polls/»)

Вместе с тем отправляется оставшийся текст «34/» в конфигурацию URL для polls.urls для дальнейшей обработки соответствия шаблону r'^(?P<question_id>[0-9]+)/$', чтобы вызвать функцию представления detail(), как показано ниже:

detail(request=<HttpRequest object>, question_id='34')

question_id='34' является частью (?P<question_id>[0-9]+), и вокруг этой модели используется окружающая скобка для «захвата» соответствующего текста, который затем передается в функцию представления; ?P<question_id> определяет имя, которое будет использоваться для распознавания соответствующей модели; а также [0-9]+ соответствует последовательности чисел (одному числу).

Поскольку шаблон URL является регулярным выражением, его можно использовать для выполнения некоторых операций, без каких-либо ограничений. И нет необходимости добавлять расширение .html –除非 вы этого хотите, в этом случае вы можете сделать это так:}}

url(r'^polls/latest\.html$', views.index),

Написать вид для реализации функции

Каждый вид отвечает за одно из двух действий: возвращает объект HttpResponse, содержащий запрошенный контент страницы, или выбрасывает исключение, такое как HTTP 404. Измените код файла polls/views.py следующим образом:

from django.http import HttpResponse
from models import Question
def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    output = ', '.join([q.question_text for q in latest_question_list])
    return HttpResponse(output)
# Leave the rest of the views (detail, results, vote) unchanged

Здесь есть проблема: веб-дизайн硬编码 в представлении. Если вы хотите изменить вид страницы, вам нужно редактировать этот Python код. Поэтому давайте используем систему шаблонов Django, чтобы разделить код Python на шаблоны, которые можно использовать в представлениях. polls/templates/polls/index.html Введите следующий код:

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

Теперь我们来更新首页视图 polls/views.py 使用以下模板(代码):

from django.http import HttpResponse
from django.template import loader
from models import Question
def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    template = loader.get_template('polls/index.html')
    context = {
        'latest_question_list': latest_question_list,
    }
    return HttpResponse(template.render(context, request))

Этот код загружает шаблон polls/index.html и передает ему контекст. Контекст является словарем, который отображает имена переменных шаблона на Python-объекты. Теперь откройте URL (http://127.0.0.1:8000/polls/) и посмотрите результат:

Краткий способ: render()

Это очень распространенный способ загрузки шаблона, заполнения контекста и рендеринга шаблона, который возвращает объект HttpResponse. Django предоставляет快捷 способ. Вот полный вид index() - перепишите polls/views.py следующим образом:

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)

Обратите внимание, что после выполнения этой операции в различных видах нам больше не нужно импортировать загрузчики и объект HttpResponse (если вы хотите сохранить HttpResponse, если у вас все еще есть короткие методы detail, results и vote).

взвращение ошибки 404

Теперь让我们解决这个问题 детального просмотра - страницы, отображающей текст вопроса опроса. Добавьте код вида (polls/views.py):

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("Вопрос не существует")
    return render(request, 'polls/detail.html', {'question': question})

Обратите внимание здесь: вид вызывает исключение HTTP404, если проблема с идентификатором запроса не существует.

Мы будем обсуждать, какие изменения можно сделать в polls/detail.html в будущем, но если нужно быстро использовать приведенный выше пример, файл polls/templates/polls/detail.html должен содержать только:


   {{question}}


Взвлечь 404-ошибку, теперь мы запросили несуществующий вопрос, например: http://127.0.0.1:8000/polls/100/, результат отображается следующим образом:

Краткий способ: get_object_or_404()

Очень распространенный способ использования get() и вызова HTTP404-ошибки. Django предоставляет краткий способ. Вот как был изменен вид 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})

Функция get_object_or_404() принимает в качестве первого параметра Django-модель и количество произвольных параметров с ключевыми словами, которые передаются в функцию get() управления моделью.

Если объект не существует, вызывается HTTP404.

Существует также функция get_list_or_404(), которая работает аналогично get_object_or_404() – только вместо метода get() используется метод filter(). Если список пуст, он вызывает HTTP404.

Использование системы шаблонов

Вернемся к нашему приложению polls и функции detail(). Из-за проблемы контекста переменных шаблон polls/detail.html выглядит следующим образом:

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


Система шаблонов использует синтаксис точечной проверки для доступа к свойствам переменных. В этом примере {{question.question_text }}, первый Django действительно ищет в словаре объекта question. Если не найдено, он пытается выполнить поиск свойств – если поиск свойств не удался, он пытается выполнить поиск по индексу списка.
Теперь проверьте написанный нами код, откройте его в браузере: http://127.0.0.1:8000/polls/5/, и получите результат:

Удалите硬кодированные URL в шаблонах

Помните, когда мы создаем ссылку на вопрос в polls/index.html, часть, которая硬кодирована, выглядит так:

  <li><a href="/polls/{{question.id}}/">{{question.question_text}}</a></li>

Проблема с этим методом, основанным на硬кодировании, заключается в том, что он требует изменения URL в множестве шаблонов. Однако, так как в модуле polls.urls определен параметр url() для имени URL, вы можете удалить зависимость от конкретного URL-пути в конфигурации URL, используя шаблонный тег {% url %}:

  <li><a href="{etail'question.id%}">{{question.question_text}}</a></li>

Этот способ работает за счет определения URL-имени для поиска в модуле polls.urls. Вы можете точно увидеть, как определено имя URL 'detail':

  ...
# the 'name' value as called by the {% url %} template tag
url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
...

Если вы хотите изменить URL-адрес детального вида голосования на другой, например polls/specifics/12/, в шаблонах (или templates), вам нужно изменить его в polls/urls.py:

  ...
# added the word 'specifics'
url(r'^specifics/(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
...

Имя URL-пространства имен

Этот учебный проект содержит только одно приложение - polls. В реальном проекте Django может быть от пяти до двух десятков и более приложений. Как Django различает их URL-адреса? Например, приложение для голосования имеет детальный вид, поэтому в одном проекте может быть то же приложение, что и в блоге. Как использовать шаблонный тег {% url %}, чтобы сообщить Django, какие приложения имеют такой вид?

Ответ заключается в добавлении пространства имен к URLconf. В файле polls/urls.py продолжайте движение, добавьте имя приложения и настройте пространство имен приложения, откройте файл polls/urls.py:

from django.conf.urls import url
from . import views
app_name = 'polls'
urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
    url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]

Теперь измените шаблон polls/index.html, откройте файл polls/templates/polls/index.html и добавьте следующий код:

  <li><a href="{etail'question.id%}">{{question.question_text}}</a></li>

Сделайте это, чтобы он указывал на пространство имён detail вид, откройте файл polls/templates/polls/index.html следующим образом:

  <li><a href="{olls:detail'question.id%}">{{question.question_text}}</a></li>