Django url template: Writing your first Django app, part 3 | Django documentation

static/(?P<path>.*)$’, ‘django.views.static.serve’,{‘document_root’: settings.MEDIA_ROOT}),
)

Мой ‘views.py’ в моем каталоге ‘login’ выглядит так:

from django.shortcuts import render_to_response, redirect
from django.template import RequestContext
from django.contrib import auth

def login_view(request):
    if request.method == 'POST':
        uname = request.POST.get('username', '')
        psword = request.POST.get('password', '')
        user = auth.authenticate(username=uname, password=psword)
        # if the user logs in and is active
        if user is not None and user.is_active:
            auth.login(request, user)
            return render_to_response('main/main.html', {}, context_instance=RequestContext(request))
            #return redirect(main_view)
        else:
            return render_to_response('loginpage.html', {'box_width': '402', 'login_failed': '1',}, context_instance=RequestContext(request))
    else:
        return render_to_response('loginpage. html', {'box_width': '400',}, context_instance=RequestContext(request))

def logout_view(request):
    auth.logout(request)
    return render_to_response('loginpage.html', {'box_width': '402', 'logged_out': '1',}, context_instance=RequestContext(request))

и, наконец, main.html, на который указывает login_view, выглядит следующим образом:

<html>
<body>
test! <a href="{% url logout_view %}">logout</a>
</body>
</html>

Так почему же я получаю ‘NoReverseMatch’ каждый раз?

*(на несколько иной ноте мне пришлось использовать ‘ context_instance=RequestContext (request)’ в конце всех моих render-to-response, потому что в противном случае он не распознал бы {{ MEDIA_URL }} в моих шаблонах, и я не мог бы ссылаться ни на один файл css или js. Я не совсем понимаю, почему это так. Мне это кажется неправильным)*

django

django-templates

django-urls

Поделиться

Источник


Robert Johnstone    

04 января 2011 в 23:13

Содержание

6 ответов


  • Django admin password_change_form template переопределен django-registration app templates

    Я использую приложение django-registration с пользовательскими шаблонами и администратором django. По какой-то причине шаблон администратора password_change_form заменяется пользовательским шаблоном из приложения регистрации. Я понятия не имею, что я здесь делаю не так. Я хочу, чтобы администратор…

  • Django templates папок

    Я экспериментирую с Django и выясняю , как установить urls.py и как работает URLs. Я настроил urls.py в корне проекта, чтобы он направлялся к моему блогу и администратору. Но теперь я хочу добавить страницу в свой дом, так что в localhost:8000 . Поэтому я добавил следующий код к urls.py в корне…



100

Выбранный ответ устарел,и никакие другие не работали для меня (Django 1.6 и [apparantly] no registered namespace.)

Для Django 1.5 и более поздних версий (из документов )

Предупреждение
Не забудьте поставить кавычки вокруг пути функции или имени шаблона!

С именем URL вы могли бы это сделать:

(r'^login/', login_view, name='login'),
. login/', 'login.views.login_view'),
 

Это стандартный способ делать вещи. Затем вы можете получить доступ к URL в ваших шаблонах с помощью:

{% url login.views.login_view %}

Поделиться


Marcus Whybrow    

04 января 2011 в 23:18



43

Убедитесь (django 1.5 и далее), что вы заключили имя url в кавычки, и если ваш url принимает параметры, они должны быть вне кавычек (я потратил часы, выясняя эту ошибку!).

{% url 'namespace:view_name' arg1=value1 arg2=value2 as the_url %}
<a href="{{ the_url }}"> link_name </a>

Поделиться


Bogatyr    

18 декабря 2014 в 20:43


  • Динамические теги с Django Templates

    Я новичок в Django Templates и нуждаюсь в некотором совете. Я пытаюсь изменить h2 в зависимости от пути url. /logout/' , logout_view, name='logout_view')

    Поделиться


    Bernhard Vallant    

    04 января 2011 в 23:24



    12

    Я столкнулся с той же проблемой.

    То, что я нашел из документации, мы должны использовать namedspace.

    в вашем случае {% url login:login_view %}

    Поделиться


    Alist    

    29 января 2014 в 07:31



    1

    Судя по вашему примеру, разве это не должно быть {% url myproject.login.views.login_view %} и конец истории? (замените myproject вашим фактическим названием проекта)

    Поделиться


    Yuji ‘Tomita’ Tomita    

    04 января 2011 в 23:51


    Похожие вопросы:

    Название модели объектов в django templates

    Есть ли какой-нибудь способ получить имя модели каких-либо объектов в django templates. Вручную мы можем попробовать это сделать, определив методы в моделях или используя теги шаблонов… Но есть ли…

    функции в django templates

    Поддерживает ли django templates функции? Могу ли я написать их встроенными в шаблон? Если смогу, то как?

    Подписка строк в django templates

    Можно ли индексировать строки в django templates ? То что я имею в виду это делать print hello[:3] => hel в django templates . Написание {{ stringVar[:10] }} бросков TemplateSyntaxError: Could…

    Django admin password_change_form template переопределен django-registration app templates

    Я использую приложение django-registration с пользовательскими шаблонами и администратором django. По какой-то причине шаблон администратора password_change_form заменяется пользовательским шаблоном…

    Django templates папок

    Я экспериментирую с Django и выясняю , как установить urls.py и как работает URLs. Я настроил urls. py в корне проекта, чтобы он направлялся к моему блогу и администратору. Но теперь я хочу добавить…

    Динамические теги с Django Templates

    Я новичок в Django Templates и нуждаюсь в некотором совете. Я пытаюсь изменить h2 в зависимости от пути url. Мое предлагаемое решение состоит в том, чтобы искать путь и циклически перебирать массив,…

    Python Django templates для куклы

    Прежде всего, мне очень жаль, потому что это наверняка дубликат. Однако я не смог найти вопроса о stackoverflow, который не касался бы функций шаблонов advanced Django. Я последовал за Django…

    Как понять Django templates?

    Вот официальный учебник Django, раздел шаблонов: Сначала создайте каталог с именем templates в каталоге polls. Django будет искать шаблоны там. В каталоге шаблонов, который вы только что создали,…

    Где находится django TEMPLATES

    Мне нужно найти Django TEMPLATES местоположение, чтобы добавить его в строку под ‘context_processors’ ом ‘OPTIONS’ Я исследовал и нашел это, которое выглядит как мой решатель проблем, однако я не. ..

    django Templates не существует execpt home url

    Я создаю простой website.and с какой-то странной ошибкой TemplateDoesNotExist at /about/ , но мой homepage работает нормально без ошибки TempaletDoesNotExist. мои оба home.html и about.html в одном…

    Встроенные шаблонные теги и фильтры — Документация Django 1.4

    Этот раздел описывает строенные шаблонные теги и фильтры Django. Рекомендуем использовать автоматическую документацию по возможности, т.к. она включает так же собственные теги и фильтры.

    Список встроенных тегов

    autoescape

    Контролирует авто-экранирование. Этот тег принимает on или off аргумент, указывающий должно ли использоваться автоматическое экранирование внутри блока. Блок закрывается закрывающим тегом endautoescape.

    Если экранирование включено, ко всем переменным будет применяется HTML-экранирование перед выводом (но после применения всех фильтров). Это эквивалентно использованию фильтра escape для каждой переменной.

    Не будут экранированы переменные помеченные как безопасные( “safe”), или кодом определяющим переменную, или после применения фильтров safe или escape.

    Примеры использования:

    {% autoescape on %}
        {{ body }}
    {% endautoescape %}
    

    block

    Определяет блок, который может быть переопределен в дочернем шаблоне. Смотрите подробности в разделе о наследовании шаблонов.

    csrf_token

    В Django 1.1.X, это ничего не делающий тег, который возвращает пустую строку, добавленный для совместимости версий. В Django 1.2 и выше, используется для CSRF защиты, как описано в разделе о Cross Site Request Forgeries.

    cycle

    Циклически перебирает переданные строки или значения каждый раз, когда выполняется тег.

    В цикле, поочередно выводит строку переданную в тег:

    {% for o in some_list %}
        <tr>
            ...
        </tr>
    {% endfor %}
    

    Вы можете так же использовать переменные. Например, если у вас есть две переменных в шаблоне, rowvalue1 и rowvalue2, вы можете переключаться между их значениями:

    {% for o in some_list %}
        <tr>
            . ..
        </tr>
    {% endfor %}
    

    Обратите внимание, что переменные используемые в качестве аргументов (rowvalue1 и rowvalue2 из примера выше) НЕ будут экранированы! Так что или убедитесь, что вы доверяете переменным, или используйте явное экранирование, например:

    {% for o in some_list %}
        <tr>
            ...
        </tr>
    {% endfor %}
    

    В можете использовать переменные и строки вместе:

    {% for o in some_list %}
        <tr>
            ...
        </tr>
    {% endfor %}
    

    В некоторых случаях вам может понадобиться обратиться к значению не в цикле. Что бы сделать это, просто передайте в тег {% cycle %} название, используя “as”, например:

    {% cycle 'row1' 'row2' as rowcolors %}
    

    Теперь вы можете использовать текущее значение цикла в любом месте шаблона используя переданное название как переменную контекста. Если вам необходимо следующее значение, используйте тег снова, используя название переменной. Следующий шаблон:

    <tr>
        <td>. ..</td>
        <td>...</td>
    </tr>
    <tr>
        <td>...</td>
        <td>...</td>
    </tr>
    

    выведет:

    <tr>
        <td>...</td>
        <td>...</td>
    </tr>
    <tr>
        <td>...</td>
        <td>...</td>
    </tr>
    

    Вы можете использовать любое количество значений в теге {% cycle %}, разделенных пробелами. Значения в одинарных (‘) или двойных кавычках («) рассматриваются как строки, в то время как, значения без кавычек, интерпретируются как переменные.

    Переменные не будут экранированы. Это потому, что теги не экранируют свое содержимое. Любой HTML или Javascript код в переменных будет выведен как есть, что может привести к проблемам с защитой.

    Для обратной совместимости, тег {% cycle %} поддерживает старый синтаксис предыдущих версий Django. Вы не должны его использовать в новых проектах, но для тех кому интересно он выглядит таким образом:

    {% cycle row1,row2,row3 %}
    

    Такой синтаксис воспринимает все как строки, и нет возможности передать переменные, использовать запятую или пробел в качестве значения. Мы уже говорили что не следует использовать этот синтаксис в новых проектах?

    Добавлено в Django 1.3.

    По-умолчанию, использование тега {% cycle %} с аргументом as выведет первое значение цикла. Это может быть проблемой, если вы хотите использовать значение во вложенном теге или в включенном теге. Если вы хотите просто определить цикл, но не выводить первое значение, используйте аргумент silent в конце тега. Например:

    {% for obj in some_list %}
        {% cycle 'row1' 'row2' as rowcolors silent %}
        <tr>{% include "subtemplate.html " %}</tr>
    {% endfor %}
    

    Это выведет список элементов <tr> с class чередующийся между row1 и row2; включенный шаблон будет иметь доступ к переменной rowcolors, которая содержит класс <tr>. Если бы аргумент silent не использовался, row1 вывелся бы в элементе <tr> как обычный тег.

    Если используется аргумент silent, он будет автоматически применен ко всем последующим вызовам этого цикла. Этот шаблон ничего не выведет, даже учитывая что второй вызов {% cycle %} не использует silent:

    {% cycle 'row1' 'row2' as rowcolors silent %}
    {% cycle rowcolors %}
    

    debug

    Выводит всю отладочную информацию, в том числе текущей контекст и импортированные модули.

    extends

    Указывает что данный шаблон наследуется от родительского.

    Может использоваться двумя способами:

    • {% extends «base.html» %} (с кавычками) использует буквальное значение «base.html» в качестве названия родительского шаблона.

    • {% extends variable %} использует значение variable. Если значение строка, Django использует ее как название родительского шаблона. Если значение переменной объект Template, Django использует этот объект как родительский шаблон.

    Смотрите подробности в Наследование шаблонов.

    filter

    Применяет фильтры к содержимому блока.

    Можно передавать группу фильтров и они могут содержать фильтры – синтаксис аналогичен выводу переменных в шаблоне.

    Примеры использования:

    {% filter force_escape|lower %}
        This text will be HTML-escaped, and will appear in all lowercase.
    {% endfilter %}
    

    Примечание

    Нельзя передавать фильтры escape и safe. Вместо этого используйте тег autoescape.

    firstof

    Выводит первую из переданных переменных, которая не равна False. НЕ экранирует значения переменных.

    Ничего не выводит, если все переменные равны False.

    Примеры использования:

    {% firstof var1 var2 var3 %}
    

    Это равносильно:

    {% if var1 %}
        {{ var1|safe }}
    {% else %}{% if var2 %}
        {{ var2|safe }}
    {% else %}{% if var3 %}
        {{ var3|safe }}
    {% endif %}{% endif %}{% endif %}
    

    Вы можете использовать сроку как значение по-умолчанию на случай, если все переменные равны False:

    {% firstof var1 var2 var3 "fallback value" %}
    

    Переменные не будут экранированы. Это потому, что теги не экранируют свое содержимое. Любой HTML или Javascript код в переменных будет выведен как есть, что может привести к проблемам с защитой. Если вам необходимо экранирование, используйте его явно:

    {% filter force_escape %}
        {% firstof var1 var2 var3 "fallback value" %}
    {% endfilter %}
    

    for

    Цикл по каждому элементу массива. Например, выведем список спортсменов из athlete_list:

    <ul>
    {% for athlete in athlete_list %}
        <li>{{ athlete.name }}</li>
    {% endfor %}
    </ul>
    

    Вы можете использовать цикл по списку в обратном порядке {% for obj in list reversed %}.

    Если вам нужен цикл по списку списков, вы можете распаковать значения под-списка на отдельные переменные. Например, если ваш контекст содержит список (x,y) координат points, вы можете использовать следующий код для их вывода:

    {% for x, y in points %}
        There is a point at {{ x }},{{ y }}
    {% endfor %}
    

    Аналогично можно использовать словарь. Например, если ваш контекст содержит словарь data, следующий код выведет ключи и значения словаря:

    {% for key, value in data.items %}
        {{ key }}: {{ value }}
    {% endfor %}
    

    Внутри цикла доступные некоторые дополнительные переменные:

    Переменная

    Описание

    forloop. counter

    Номер текущей итерации цикла начиная с 1

    forloop.counter0

    Номер текущей итерации цикла начиная с 0

    forloop.revcounter

    Номер текущей итерации цикла начиная с конца с 1

    forloop.revcounter0

    Номер текущей итерации цикла начиная с конца с 0

    forloop.first

    True, если это первая итерация

    forloop.last

    True, если это последняя итерация

    forloop.parentloop

    Для вложенных циклов, это “внешний” цикл.

    for … empty

    Тег for содержит необязательную часть {% empty %}, которая будет отображена, если список пуст или не найден:

    <ul>
    {% for athlete in athlete_list %}
        <li>{{ athlete.name }}</li>
    {% empty %}
        <li>Sorry, no athlete in this list!</li>
    {% endfor %}
    <ul>
    

    Это эквивалентно, но короче, читабельней и возможно быстрее, такому коду:

    <ul>
      {% if athlete_list %}
        {% for athlete in athlete_list %}
          <li>{{ athlete. name }}</li>
        {% endfor %}
      {% else %}
        <li>Sorry, no athletes in this list.</li>
      {% endif %}
    </ul>
    

    if

    Тег {% if %} вычисляет переменную и если она равна “true” (то есть существует, не пустая и не равна “false”) выводит содержимое блока:

    {% if athlete_list %}
        Number of athletes: {{ athlete_list|length }}
    {% elif athlete_in_locker_room_list %}
        Athletes should be out of the locker room soon!
    {% else %}
        No athletes.
    {% endif %}
    

    В примере выше, если athlete_list не пустой, будет отображено количество спортсменов {{ athlete_list|length }}.

    Как вы можете видеть, тег if может содержать один или несколько блоков « {% elif %}«, так же как и блок {% else %}, который будет выведен, если все предыдущие условия не верны. Все эти блоки не обязательны.

    Добавлено в Django 1.4.

    Тег if теперь поддерживает блок {% elif %}.

    Булевы операторы

    Тег if может использовать and, or или not:

    {% if athlete_list and coach_list %}
        Both athletes and coaches are available. 
    {% endif %}
    
    {% if not athlete_list %}
        There are no athletes.
    {% endif %}
    
    {% if athlete_list or coach_list %}
        There are some athletes or some coaches.
    {% endif %}
    
    {% if not athlete_list or coach_list %}
        There are no athletes or there are some coaches (OK, so
        writing English translations of boolean logic sounds
        stupid; it's not our fault).
    {% endif %}
    
    {% if athlete_list and not coach_list %}
        There are some athletes and absolutely no coaches.
    {% endif %}
    

    Изменено в Django 1.2.

    Можно использовать and и or вместе, операция and имеет больший приоритет чем or, например:

    {% if athlete_list and coach_list or cheerleader_list %}
    

    будет интерпретировано как:

    if (athlete_list and coach_list) or cheerleader_list
    

    Использовать скобки в теге if нельзя. Если вам нужно указать приоритет, используйте вложенные теги if.

    Добавлено в Django 1.2.

    Тег if может использовать операторы ==, !=, <, >, <=, >= и in которые работают таким образом:

    Оператор ==

    Равенство. Например:

    {% if somevar == "x" %}
      This appears if variable somevar equals the string "x"
    {% endif %}
    

    Оператор !=

    Неравенство. Например:

    {% if somevar != "x" %}
      This appears if variable somevar does not equal the string "x",
      or if somevar is not found in the context
    {% endif %}
    

    Оператор <

    Меньше чем. Например:

    {% if somevar < 100 %}
      This appears if variable somevar is less than 100.
    {% endif %}
    

    Оператор >

    Больше чем. Например:

    {% if somevar > 0 %}
      This appears if variable somevar is greater than 0.
    {% endif %}
    

    Оператор <=

    Меньше чем или равно. Например:

    {% if somevar <= 100 %}
      This appears if variable somevar is less than 100 or equal to 100.
    {% endif %}
    

    Оператор >=

    Больше чем или равно. Например:

    {% if somevar >= 1 %}
      This appears if variable somevar is greater than 1 or equal to 1.
    {% endif %}
    

    Оператор in

    Вхождение в. Этот оператор поддерживается большинством контейнеров Python, что бы проверит входит ли значение в контейнер. Несколько примеров как работает x in y:

    {% if "bc" in "abcdef" %}
      This appears since "bc" is a substring of "abcdef"
    {% endif %}
    
    {% if "hello" in greetings %}
      If greetings is a list or set, one element of which is the string
      "hello", this will appear.
    {% endif %}
    
    {% if user in users %}
      If users is a QuerySet, this will appear if user is an
      instance that belongs to the QuerySet.
    {% endif %}
    

    Оператор not in

    Не вхождение в. Оператор обратный оператору in.

    Операторы сравнения не могут использовать вместе как в Python или математике. Например, вместо использования:

    {% if a > b > c %}  (WRONG)
    

    вы должны использовать:

    Фильтры

    Вы можете использовать фильтры в выражении if. Например:

    {% if messages|length >= 100 %}
       You have lots of messages today!
    {% endif %}
    

    Сложные выражения

    Все перечисленное выше может быть использовано вместе для создания сложных выражений. Для таких выражений, важно знать как операторы группируются при выполнении выражения — то есть, правила приоритета. Приоритет операторов, от низшего к высшему, выглядит следующим образом:

    • or
    • and
    • not
    • in
    • ==, !=, <, >, <=, >=

    (Это точно повторяет Python). Таким образом, например, следующий сложный тег if:

    {% if a == b or c == d and e %}
    

    …будет интерпретирован как:

    (a == b) or ((c == d) and e)
    

    Если вам нужен другой приоритет, используйте вложенные теги if. Иногда этот способ более понятен, во всяком случае, для тех, кто не знает правил приоритета.

    ifchanged

    Проверяет было ли изменено значение с предыдущей итерации цикла.

    Блочный тег {% ifchanged %} используется внутри цикла. Существует два способа использовать тег.

    1. Проверять содержимое тега и если оно было изменено с последней итерации, отображать его. Например, этот код отображает список дней и отображает месяц только при его изменении:

      <h2>Archive for {{ year }}</h2>
      
      {% for date in days %}
          {% ifchanged %}<h4>{{ date|date:"F" }}</h4>{% endifchanged %}
          <a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a>
      {% endfor %}
      
    2. Если передано одна или более переменных, проверяет была ли изменена одна из переменных. Например, следующий код отображает дату при каждом изменении, в то же время отображает час, если час или дата были изменены:

      {% for date in days %}
          {% ifchanged date.date %} {{ date.date }} {% endifchanged %}
          {% ifchanged date.hour date.date %}
              {{ date.hour }}
          {% endifchanged %}
      {% endfor %}
      

    Тег ifchanged может содержать не обязательный блок {% else %}, который будет отображаться, если значение не изменилось:

    {% for match in matches %}
        <divred" "blue" %}
            {% else %}
                grey
            {% endifchanged %}
        ">{{ match }}</div>
    {% endfor %}
    

    ifequal

    Выводит содержимое блока, если два аргумента равны

    Например:

    {% ifequal user.id comment.user_id %}
        ...
    {% endifequal %}
    

    Как и в теге if можно использовать не обязательный блок {% else %}.

    Аргументом может быть строка:

    {% ifequal user.username "adrian" %}
        ...
    {% endifequal %}
    

    Вы можете сравнивать переменные шаблона или строки. Вы не можете сравнивать с объектами Python такими как True или False. Если вам нужно проверить что-то на истинность, используйте тег if.

    ifnotequal

    Аналогичен тегу ifequal, но проверяет аргументы на неравенство.

    include

    Загружает шаблон и выводит его с текущим контекстом. Это способ “включить” один шаблон в другой.

    Названия шаблона можно указать переменной или строкой в одинарных или двойных кавычках.

    Это пример включает содержимое шаблона «foo/bar.html»:

    {% include "foo/bar.html" %}
    

    Этот пример включает содержимое шаблона, чье имя содержится в переменной template_name:

    {% include template_name %}
    

    Включенный шаблон выполняется с контекстом шаблона, который его включает. Этот пример выводит «Hello, John»:

    Вы можете передать дополнительные переменные контекста в шаблон используя именованные аргументы:

    {% include "name_snippet.html" with person="Jane" greeting="Hello" %}
    

    Если вы хотите выполнить шаблон используя только указанные переменные в контексте (или не используя переменные совсем), добавите параметр only:

    {% include "name_snippet. html" with greeting="Hi" only %}
    

    Примечание

    Тег include должен восприниматься как “выполним этот под-шаблон и включим полученный HTML”, а не “парсим этот под-шаблон и включаем его как часть родительского”. Это означает, что нет никакого общего состояния между включенными шаблонами – каждое включение это полностью независимый процесс.

    Смотрите так же: {% ssi %}.

    load

    Загружает библиотеку тегов.

    Например, следующий шаблон загрузил бы все теги и фильтры зарегистрированные в somelibrary и otherlibrary который находится в пакете package:

    {% load somelibrary package.otherlibrary %}
    

    Изменено в Django 1.3.

    Вы можете так же загрузить определенные теги и фильтры из библиотеки, используя аргумент from. В этом примере, шаблонные теги/фильтры foo и bar будут загружены с somelibrary:

    {% load foo bar from somelibrary %}
    

    Смотрите раздел о собственных библиотеках фильтров и тегов.

    now

    Отображает текущую дату и/или время, используя формат соответственно переданной строке. Эта строка может содержать символы форматирования описанные в разделе о фильтре date.

    Например:

    It is {% now "jS F Y H:i" %}
    

    Вы можете экранировать символ форматирования с помощью слэша, что бы использовать его как строку. В этом примере, “f” экранирован, т.к. в другом случае “f” будет использован как строка форматирования отображающая время. Символ “o” не экранирован т.к. это не символ форматирования:

    It is the {% now "jS o\f F" %}
    

    Этот пример выведет “It is the 4th of September”.

    Изменено в Django 1.4.

    regroup

    Группирует объекты по общему атрибуту.

    Этот сложный тег лучше всего объяснить с помощью примера: people – список людей представленный словарями с ключами first_name, last_name и gender:

    people = [
        {'first_name': 'George', 'last_name': 'Bush', 'gender': 'Male'},
        {'first_name': 'Bill', 'last_name': 'Clinton', 'gender': 'Male'},
        {'first_name': 'Margaret', 'last_name': 'Thatcher', 'gender': 'Female'},
        {'first_name': 'Condoleezza', 'last_name': 'Rice', 'gender': 'Female'},
        {'first_name': 'Pat', 'last_name': 'Smith', 'gender': 'Unknown'},
    ]
    

    . ..и вам нужно отобразить список отсортированный по полу:

    • Male:
    • Female:
      • Margaret Thatcher
      • Condoleezza Rice
    • Unknown:

    Вы можете использовать тег {% regroup %} что бы сгруппировать список по полу(gender). Следующий шаблон делает это:

    {% regroup people by gender as gender_list %}
    
    <ul>
    {% for gender in gender_list %}
        <li>{{ gender.grouper }}
        <ul>
            {% for item in gender.list %}
            <li>{{ item.first_name }} {{ item.last_name }}</li>
            {% endfor %}
        </ul>
        </li>
    {% endfor %}
    </ul>
    

    Давайте изучим этот пример. {% regroup %} принимает три аргумента: список, который вы хотите перегруппировать; атрибут, по которому нужно сгруппировать, и название переменной с результатами. В этом примере, мы перегруппируем список people по атрибуту gender и используем результат gender_list.

    {% regroup %} создает список (в нашем случае gender_list) из групп объектов. Каждый объект группы содержит два атрибута:

    • grouper – значение, по которому происходила группировка (например, строка “Male” или “Female”).

    • list – список объектов в группе (например, список всех людей с gender=’Male’).

    Заметим, {% regroup %} не сортирует переданный список! Наш пример опирается на тот факт, что список people был изначально отсортирован по gender. Если элементы списка people не были бы отсортированы по gender, перегруппировка отобразила бы несколько групп для одного пола. Например, список people был таким (заметьте, что мужчины не сгруппированы вместе):

    people = [
        {'first_name': 'Bill', 'last_name': 'Clinton', 'gender': 'Male'},
        {'first_name': 'Pat', 'last_name': 'Smith', 'gender': 'Unknown'},
        {'first_name': 'Margaret', 'last_name': 'Thatcher', 'gender': 'Female'},
        {'first_name': 'George', 'last_name': 'Bush', 'gender': 'Male'},
        {'first_name': 'Condoleezza', 'last_name': 'Rice', 'gender': 'Female'},
    ]
    

    В результате применения тега {% regroup %} для списка выше получим такой результат:

    • Male:
    • Unknown:
    • Female:
    • Male:
    • Female:

    Самый простой способ решить эту проблему удостоверится, что данные отсортированы так, как должны быть отображены.

    Еще один способ отсортировать в шаблоне используя фильтр dictsort, если ваши данные это список словарей:

    {% regroup people|dictsort:"gender" by gender as gender_list %}
    

    Группировка по другим свойствам

    Можно группировать объекты по методу, атрибуту, ключу словаря и списку объектов, в общем по всему, к чему можно получить доступ в шаблоне. Например, если “gender” это внешний ключ на модель с атрибутом “description,” вы можете использовать:

    {% regroup people by gender.description as gender_list %}
    

    Или, если gender это поле с choices, будет доступен метод django.db.models.Model.get_FOO_display() позволяя сгруппировать по отображаемым названиям, а не значениям choices:

    {% regroup people by get_gender_display as gender_list %}
    

    {{ gender.grouper }} теперь будет отображать значение поля, а не ключи choices.

    spaceless

    Убирает пробелы между HTML тегами, включая символы табуляции и перенос строки.

    Пример использования:

    {% spaceless %}
        <p>
            <a href="foo/">Foo</a>
        </p>
    {% endspaceless %}
    

    Этот пример вернет такой HTML:

    <p><a href="foo/">Foo</a></p>
    

    Будут удалены пробелы только между тегами, и оставит между тегами и текстом. В этом примере пробелы вокруг Hello не будут удалены:

    {% spaceless %}
        <strong>
            Hello
        </strong>
    {% endspaceless %}
    

    ssi

    Выводит содержимое файла в шаблон.

    Как и тег include, {% ssi %} добавляет содержимое другого файла, который должен быть указан через абсолютный путь, в текущий шаблон:

    {% ssi /home/html/ljworld.com/includes/right_generic.html %}
    

    Если используется не обязательный параметр “parsed”, содержимое включаемого файла будет выполнено как код шаблона используя текущий контекст:

    {% ssi /home/html/ljworld.com/includes/right_generic.html parsed %}
    

    Если вы используете {% ssi %}, определите параметр ALLOWED_INCLUDE_ROOTS в настройках Django, в качестве меры безопасности.

    Смотрите так же: {% include %}.

    Forwards compatibility

    Изменено в Django 1.3.

    В Django 1.5, поведение тега ssi будет изменено и будет принимать переменную контекста, а не значение без кавычек.

    Для простоты обновления версии Django, в версию 1.3 добавлена версия тега в библиотеку future, которая поддерживает новое поведение. Что бы использовать этот тег, добавьте вызов тега load в начале шаблона, и заключите в кавычки первый аргумент тега ssi. Например:

    {% load ssi from future %}
    {% ssi '/home/html/ljworld.com/includes/right_generic.html' %}
    

    В Django 1.5 тег будет заменен версией из библиотеки тегов future. Для простоты обновления Django используйте новый синтаксис.

    templatetag

    Выводит один из символов, которые используются для определения тегов.

    Так как система шаблонов не поддерживает “экранирование”, для отображения элементов синтаксиса необходимо использовать тег {% templatetag %}.

    Аргумент указывает какой элемент синтаксиса отображать:

    Аргумент

    Вывод

    openblock{%
    closeblock%}
    openvariable{{
    closevariable}}
    openbrace{
    closebrace}
    opencomment{#
    closecomment#}

    url

    Возвращает абсолютную ссылку (URL без имени домена) соответствующую указанному представлению с необязательными аргументами. clients/’, include(‘project_name.app_name.urls’))

    …в шаблоне можно создать ссылку на представление:

    {% url app_views.client client.id %}
    

    Тег вернет такую строку /clients/client/123/.

    Если вы используете именованные шаблоны URL, можно указать имя шаблона в теге url вместо пути к представлению.

    Если вы пытаетесь вывести URL который не существует, будет вызвано исключение django.core.urlresolvers.NoReverseMatch, и ваш сайт покажет страницу с ошибкой.

    Если вам нужно получить URL без его отображения:

    {% url path.to.view arg arg2 as the_url %}
    
    <a href="{{ the_url }}">I'm linking to {{ the_url }}</a>
    

    Такой {% url … as var %} синтаксис не вызовет исключение, если представление отсутствует. На практике вы будете использовать его для отображения ссылок на необязательные представления:

    {% url path.to.view as the_url %}
    {% if the_url %}
      <a href="{{ the_url }}">Link to optional stuff</a>
    {% endif %}
    

    Если вы хотите использовать URL с указанным пространством имен, укажите полное имя:

    {% url myapp:view-name %}
    

    Это приведет к использованию стандартной стратегии разрешения пространств имен в URL, включая использование данных контекста для определения текущего приложения.

    Изменено в Django 1.2.

    Для обратной совместимости, тег {% url %} поддерживает старый синтаксис разделения аргументов запятыми. Вы не должны его использовать в новых проектах. Для тех, кому интересно, пример как он выглядит:

    {% url path.to.view arg,arg2 %}
    {% url path.to.view arg, arg2 %}
    

    Этот синтаксис не поддерживает использование запятых и знака равно в аргументах.

    Forwards compatibility

    Изменено в Django 1.3.

    В Django 1.5 поведение тега url будет изменено, первый аргумент будет переменной контекста, а не название шаблона URL без кавычек.

    Для простоты обновления версии Django, в версию 1.3 добавлена версия тега в библиотеку future, которая поддерживает новое поведение. Что бы использовать этот тег, добавьте вызов тега load в начале шаблона, и заключите в кавычки первый аргумент тега url. Например:

    {% load url from future %}
    
    
    {% url 'app_views.client' %}
    
    {% url 'myapp:view-name' %}
    
    {% with view_path="app_views. client" %}
    {% url view_path client.id %}
    {% endwith %}
    
    {% with url_name="client-detail-view" %}
    {% url url_name client.id %}
    {% endwith %}
    

    Новый тег так же не поддерживает разделение аргументов url запятыми.

    В Django 1.5 тег будет заменен версией из библиотеки тегов future. Для простоты обновления Django используйте новый синтаксис.

    widthratio

    Для создания гистограмм и других графиков, этот тег вычисляет отношение переданного значения к максимальному, а затем умножает отношение на константу.

    Например:

    <img src="bar.gif" />
    

    Если this_value равно 175 и max_value равно 200, изображение из примера выше будет шириной 88 пикселей (так как 175/200 = .875; .875 * 100 = 87.5 что приблизительно равно 88).

    with

    Кэширует сложные переменные под простым названием. Это полезно при использовании “тяжелых” методов (например, тех, которые выполняют запрос к базе данных) несколько раз.

    Например:

    {% with total=business. employees.count %}
        {{ total }} employee{{ total|pluralize }}
    {% endwith %}
    

    Указанная переменная (в примере выше, total) доступна только между тегами {% with %} и {% endwith %}.

    Вы можете указать больше одной переменной контекста:

    {% with alpha=1 beta=2 %}
        ...
    {% endwith %}
    

    Примечание

    Предыдущий синтаксис так же работает: {% with business.employees.count as total %}

    Список встроенных фильтров

    add

    Суммирует аргумент и значение.

    Например:

    Если value равно 4, будет выведено 6.

    Фильтр попытается преобразовать оба значения в целое число. Если это не удастся, он будет пытаться добавить значения в любом случае. Это работает для некоторых типов (строки, списки и др.) и не работает с другими. Если ничего не получится, будет выведена пустая строка.

    Например, у нас есть:

    и first равно [1, 2, 3] и second равно [4, 5, 6], тогда результат будет [1, 2, 3, 4, 5, 6].

    Предупреждение

    Строки, которые могут быть преобразованы в числа, будут суммированы, а не объединены, как показано в примере выше.

    addslashes

    Добавляет слэш перед кавычкой. Удобно при экранировании строк в CSV, например.

    Например:

    Если value равно «I’m using Django», результат будет «I\’m using Django».

    capfirst

    Делает заглавным первый символ значения.

    Например:

    Если value равно «django», результат будет «Django».

    center

    Центрирует значение в поле заданной ширины.

    Например:

    "{{ value|center:"15" }}"
    

    Если value равно «django», результат будет »     Django    «.

    cut

    Удаляет значение аргумента из строки, к которой применяется фильтр.

    Например:

    Если value равно «String with spaces», результат будет «Stringwithspaces».

    date

    Форматирует дату в соответствии с указанным форматом.

    Использует формат функции date() в PHP (http://php.net/date) с небольшими отличиями.

    Доступное форматирование:

    Символ форматирования

    Описание

    Пример вывода

    a

    ‘a. m.’ или ‘p.m.’ (немного отличается от функции PHP, так как отображает в стиле Associated Press.)

    ‘a.m.’
    A

    ‘AM’ или ‘PM’.

    ‘AM’
    b

    Название месяца, 3-х буквенное, в нижнем регистре.

    ‘jan’
    B

    Не используется.

     
    c

    ISO 8601 формат. (Заметим: в отличии от других форматов, таких как “Z”, “O” или “r”, формат “c” не добавит временную зону для относительного времени (смотрите datetime.tzinfo).

    2008-01-02T10:30:00.000123+02:00, или 2008-01-02T10:30:00.000123 если время относительное

    d

    День месяца, 2 цифры с ведущим нулем.

    От ’01’ до ’31’

    D

    День недели, 3-х буквенное текстовое название.

    ‘Fri’
    e

    Название временной зоны. Может быть в любом формате, или вернуть пустую строку в зависимости от объекта даты.

    », ‘GMT’, ‘-500’, ‘US/Eastern’ и др.

    E

    Название месяца, зависит от текущего языка. Используется для отображения полного называния даты.

    ‘listopada’ (для польского языка, не ‘Listopad’)

    f

    Время, час в 12-часовом формате и минуты, минуты не отображаются если равны нулю. Собственное расширение.

    ‘1’, ‘1:30’
    F

    Название месяца, текстовое, длинное.

    ‘January’
    g

    Час, 12-часовом формате без ведущих нулей.

    От ‘1’ до ’12’

    G

    Час, 24-часовой формат

    От ‘0’ до ’23’

    h

    Час, 12-часовой формат.

    От ’01’ до ’12’

    H

    Час, 24-часовой формат.

    От ’00’ до ’23’

    i

    Минуты.

    От ’00’ до ’59’

    I

    Не используется.

     
    j

    День месяца без ведущего нуля.

    От ‘1’ до ’31’

    l

    Название дня недели, текстовое, длинное.

    ‘Friday’
    L

    Булево значение указывающее високосный ли год.

    True или False

    m

    Месяц, 2-цифирный с ведущими нулями.

    От ’01’ до ’12’

    M

    Название месяца, текстовое, 3-х буквенное.

    ‘Jan’
    n

    Номер месяца без ведущего нуля.

    От ‘1’ до ’12’

    N

    Аббревиатура названия месяца в формате Associated Press. Собственное расширение.

    ‘Jan.’, ‘Feb.’, ‘March’, ‘May’
    o

    week-numbering год в соответствии с ISO-8601

    ‘1999’
    O

    Разница с временем по Гринвичу

    ‘+0200’
    P

    Время, в 12-часовом формате, минуты и ‘a. m.’/’p.m.’, минуты упускаются если равны нулю, значения ‘midnight’ и ‘noon’ используются по возможности. Собственное расширение.

    ‘1 a.m.’, ‘1:30 p.m.’, ‘midnight’, ‘noon’, ’12:30 p.m.’
    r

    Дата в формате RFC 2822.

    ‘Thu, 21 Dec 2000 16:01:07 +0200’
    s

    Секунды, 2-цифирный формат без ведущих нулей.

    От ’00’ до ’59’

    S

    Английский суффикс для дня месяца, 2 символа.

    ‘st’, ‘nd’, ‘rd’ или ‘th’

    t

    Количество дней в месяце.

    От 28 до 31

    T

    Часовой пояс сервера.

    ‘EST’, ‘MDT’
    u

    микросекунды

    От 0 до 999999

    U

    Секунды с начала эпохи Unix (1 января 1970 00:00:00 UTC).

     
    w

    Номер дня недели, без ведущих нулей.

    от ‘0’ (воскресение) до ‘6’ (субота)

    W

    Норме недели в году в соответствии с ISO-8601, первая неделя начинается с понедельника.

    1, 53
    y

    Год, 2 цифры.

    ’99’
    Y

    Год, 4 цифры.

    ‘1999’
    z

    Номер дня в году.

    От 0 до 365

    Z

    Смещения часового пояса в секундах. Для часового пояса западнее UTC значение будет отрицательным, для тех, что восточнее UTC – положительным.

    От -43200 до 43200

    Добавлено в Django 1.2.

    Форматирование c и u добавлены в Django 1.2.

    Добавлено в Django 1.4.

    Форматирование e и o добавлены в Django 1.4.

    Например:

    {{ value|date:"D d M Y" }}
    

    Если value равно объекту datetime (например, результат выполнения datetime.datetime.now()), будет выведено значение ‘Wed 09 Jan 2008’.

    Переданный формат может быть одним из предопределенных(DATE_FORMAT, DATETIME_FORMAT, SHORT_DATE_FORMAT или SHORT_DATETIME_FORMAT) или любой другой сформированный из символов форматирования из таблицы выше. Предопределенные форматы зависят от текущего языка и настройки Формат локализации, например:

    Предположим что USE_L10N равно True и LANGUAGE_CODE равно «es», тогда:

    {{ value|date:"SHORT_DATE_FORMAT" }}
    

    результат вывода будет «09/01/2008» (формат «SHORT_DATE_FORMAT» для языка es указан в Django как «d/m/Y»).

    Если форматирование не указано:

    …будет использовано значение из настройки DATE_FORMAT без учета текущего языка.

    default

    Если значение равно False, будет использовано значение по-умолчанию. В противном случае используется значение.

    Например:

    {{ value|default:"nothing" }}
    

    Если value равно «» (пустая строка), будет выведено nothing.

    default_if_none

    Если (и только в этом случае) значение равно None, будет использовано значение по-умолчанию. В противном случае используется значение.

    Заметим, если передана пустая строка, значение по-умолчанию не будет использовано. Используйте фильтр default, если нужно учитывать пустую строку.

    Например:

    {{ value|default_if_none:"nothing" }}
    

    Если value равно None, будет выведено «nothing».

    dictsort

    Принимает список словарей и возвращает список отсортированный по указанному ключу.

    Например:

    {{ value|dictsort:"name" }}
    

    Если value равно:

    [
        {'name': 'zed', 'age': 19},
        {'name': 'amy', 'age': 22},
        {'name': 'joe', 'age': 31},
    ]
    

    будет возвращено:

    [
        {'name': 'amy', 'age': 22},
        {'name': 'joe', 'age': 31},
        {'name': 'zed', 'age': 19},
    ]
    

    dictsortreversed

    Принимает список словарей и возвращает список отсортированный по указанному ключу в обратном порядке. Работает аналогично фильтру выше, но возвращает список в обратном порядке.

    divisibleby

    Возвращает True, если значение делится на аргумент.

    Например:

    {{ value|divisibleby:"3" }}
    

    Если value равно 21, будет возвращено True.

    escape

    Экранирует HTML. В частности выполняются такие замены:

    • < заменяется на &lt;

    • > заменяется на &gt;

    • ‘ (одинарная кавычка) заменяется на &#39;

    • » (двойная кавычка) заменяется на &quot;

    • & заменяется на &amp;

    Экранирование применяется к выводимой строке, и нет разницы где в цепочке фильтров будет добавлен escape: он всегда будет применяться так, как будто это последний фильтр. Если экранирование необходимо сразу применить, используйте фильтр force_escape.

    Применение escape к переменной, которая уже была экранирована с помощью авто-экранирования, безопасно. Будет применено только одно экранирование. Так что безопасно использовать его с авто-экранированием. Если вам нужно применить экранирование несколько раз, используйте force_escape.

    escapejs

    Экранирует символы в строке, используемой в JavaScript. Это не делает сроку безопасной для использования в HTML, но защищает от синтаксических ошибок при генерации JavaScript/JSON.

    Например:

    Если value равно «testing\r\njavascript \’string» <b>escaping</b>», будет выведено «testing\\u000D\\u000Ajavascript \\u0027string\\u0022 \\u003Cb\\u003Eescaping\\u003C/b\\u003E».

    filesizeformat

    Форматирует размер файла в читабельном формате (например. ’13 KB’, ‘4.1 MB’, ‘102 bytes’ и др.).

    Например:

    {{ value|filesizeformat }}
    

    Если value равно 123456789, будет выведено 117.7 MB.

    first

    Возвращает первый элемент списка.

    Например:

    Если value равно [‘a’, ‘b’, ‘c’], будет возвращено ‘a’.

    fix_ampersands

    Примечание

    Этот фильтр редко когда полезен т.к. символ амперсанда экранируется автоматически . Смотрите escape.

    Заменяет амперсанд &amp;.

    Например:

    {{ value|fix_ampersands }}
    

    Если value равно Tom & Jerry, будет возвращено Tom &amp; Jerry.

    Однако, амперсанд в словах не будет заменен. Например, если value равно Caf&eacute;, вывод будет не Caf&amp;eacute; а останется Caf&eacute;. Это означает, что в некоторых случаях, например сокращение с последующей точкой с запятой, фильтр не заменит амперсанд. Например, если value равно Contact the R&D;, вывод будет без замены &D;.

    floatformat

    При использовании без аргументов, округляет число с плавающей запятой до одной десятой. Дробная часть отображается только, если существует. Например:

    value

    Шаблон

    Вывод

    34.23234{{ value|floatformat }}34.2
    34.00000{{ value|floatformat }}34
    34.26000{{ value|floatformat }}34.3

    Если используется целочисленный аргумент, floatformat округляет до указанного количества знаков после запятой. Например:

    value

    Шаблон

    Вывод

    34.23234{{ value|floatformat:3 }}34.232
    34.00000{{ value|floatformat:3 }}34.000
    34.26000{{ value|floatformat:3 }}34.260

    Если аргумент отрицательный, floatformat округляет до указанного количества знаков после запятой – но дробная часть отображается только если существует. Например:

    value

    Шаблон

    Вывод

    34.23234{{ value|floatformat:»-3″ }}34.232
    34.00000{{ value|floatformat:»-3″ }}34
    34.26000{{ value|floatformat:»-3″ }}34.260

    Использование floatformat без аргументов эквивалентно floatformat с -1.

    force_escape

    Применяет экранирование HTML к строке (смотрите escape). Это фильтр применяется сразу и возвращает новую экранированную строку. Это полезно в редких случаях, если вам необходимо применить экранирование несколько раз, или если необходимо применить другие фильтры в экранированной строке.

    get_digit

    Принимает число и возвращает запрашиваемую цифру, где 1 самая правая цифра, 2 — вторая с права, и тд. Возвращает оригинальное значение, если оно не верно (не число или меньше 1). В противном случае, всегда выводится целое число.

    Например:

    {{ value|get_digit:"2" }}
    

    Если value равно 123456789, будет выведено 8.

    iriencode

    Конвертирует IRI (Internationalized Resource Identifier) в строку, которая может быть использована в URL. Это необходимо, если вы хотите использовать не ASCII символы в URL.

    Можно использовать этот фильтр после использования фильтра urlencode.

    Например:

    Если value равно «?test=1&me=2», вывод будет «?test=1&amp;me=2».

    join

    Объединяет список используя указанную строку, аналог str.join(list) в Python

    Например:

    Если value равно списку [‘a’, ‘b’, ‘c’], вывод будет «a // b // c».

    last

    Возвращает последний элемент списка.

    Например:

    Если value равно [‘a’, ‘b’, ‘c’, ‘d’], выведет «d».

    length

    Возвращает размер значения. Работает для строк и списков.

    Например:

    Если value равно [‘a’, ‘b’, ‘c’, ‘d’], выведет 4.

    length_is

    Возвращает True, если размер значения равен аргументу, и False в противном случае.

    Например:

    {{ value|length_is:"4" }}
    

    Если value равно [‘a’, ‘b’, ‘c’, ‘d’], вернет True.

    linebreaks

    Заменяет переносы строки аналогами из HTML; один перенос строки будет заменен на <br />, новая строка с предыдущей пустой строкой оборачиваются в тег </p>.

    Например:

    Если value равно Joel\nis a slug, вывод будет <p>Joel<br />is a slug</p>.

    linebreaksbr

    Заменяет все переносы строки на <br />.

    Например:

    Если value равно Joel\nis a slug, вывод будет Joel<br />is a slug.

    linenumbers

    Отображает текст с номерами строк.

    Например:

    Если value равно:

    вернет:

    ljust

    Выравнивает значение влево в поле указанной ширины.

    Аргумент: размер поля

    Например:

    Если value равно Django, выведет «Django    «.

    lower

    Конвертирует строку в нижний регистр.

    Например:

    Если value равно Still MAD At Yoko, выведет still mad at yoko.

    make_list

    Превращает значение в список. Для строк это будет список символов. Число сначала конвертируется в unicode, а потом в список.

    Например:

    Если value равно строке «Joel», будет возвращен список [u’J’, u’o’, u’e’, u’l’]. Если value равно 123, вернет список [u’1′, u’2′, u’3′].

    phone2numeric

    Преобразует телефонный номер (возможно, содержащий буквы) в его числовой эквивалент.

    Значение не должно быть правильным телефонным номером, будет преобразована любая строка.

    Например:

    {{ value|phone2numeric }}
    

    Если value равно 800-COLLECT, выведет 800-2655328.

    pluralize

    Возвращает суффикс множественного числа, если значение не 1. По-умолчанию использует суффикс ‘s’.

    Например:

    You have {{ num_messages }} message{{ num_messages|pluralize }}.
    

    Если num_messages равно 1, выведет You have 1 message. Если num_messages равно 2 выведет You have 2 messages.

    Для слов, которые используют суффикс отличный от ‘s’, вы можете указать его как аргумент.

    Например:

    You have {{ num_walruses }} walrus{{ num_walruses|pluralize:"es" }}.
    

    Для слов, которые не преобразуются в множественную форму добавлением суффикса, вы можете указать как одинарный так и множественный суффиксы, разделенные запятыми.

    Например:

    You have {{ num_cherries }} cherr{{ num_cherries|pluralize:"y,ies" }}.
    

    Примечание

    Используйте blocktrans для переводимых строк.

    pprint

    “Врапер” для pprint.pprint() – используется для отладки.

    random

    Возвращает случайный элемент из списка.

    Например:

    Если value равно [‘a’, ‘b’, ‘c’, ‘d’], вернет «b».

    rjust

    Выравнивает значение вправо в поле указанной ширины.

    Аргумент: размер поля

    Например:

    Если value равно Django, вернет »    Django».

    safe

    Помечает строку, как требующую последующего HTML экранирования. Если авто-экранирование отключено, этот фильтр ничего не изменит.

    Примечание

    Если вы используете цепочку фильтров, фильтр примененный после safe может снова сделать переменную не безопасной. Например, следующий код выведет переменную без экранирования:

    safeseq

    Применяет фильтр safe к каждому элементу последовательности. Полезно применять с другими тегами работающими с последовательностями, такими как join. Например:

    {{ some_list|safeseq|join:", " }}
    

    Вы не можете использовать фильтр safe в таком случае, так как он сначала преобразует значение в строку.

    slugify

    Конвертирует в нижний регистр, удаляет нетекстовые символы (все кроме букв, цифр и символов подчеркивания) и преобразует пробелы в дефисы. Так же удаляет пробелы в начале и в конце строки.

    Например:

    Если value равно «Joel is a slug», вернет «joel-is-a-slug».

    stringformat

    Форматирует значение в соответствии с аргументом, который является спецификатором форматирования строк. Спецификатор использует синтаксис форматирования строк Python, с той лишь разницей, что ведущий символ “%” опущен.

    Смотрите документацию Python о форматировании строк http://docs.python.org/library/stdtypes.html#string-formatting-operations

    Например:

    {{ value|stringformat:"s" }}
    

    Если value равно «Joel is a slug», выведет «Joel is a slug».

    time

    Форматирует время в соответствии с указанным форматом.

    Можно использовать предопределенный TIME_FORMAT, или собственный формат аналогичный формату описанному в date. Заметим, что предопределенный формат зависит от текущего языка.

    Фильтр принимает только параметры в строке формата, которые относятся к времени, а не дате (по понятным причинам). Если вам нужно отформатировать дату, используйте фильтр date.

    Например:

    Если value равно datetime.datetime.now(), может вернуть «01:23».

    Другой пример:

    Предположим USE_L10N равно True и LANGUAGE_CODE равно «de», тогда:

    {{ value|time:"TIME_FORMAT" }}
    

    будет возвращена строка «01:23:00» (формат «TIME_FORMAT» для языка de определен в Django как «H:i:s»).

    Если форматирование не указано:

    …будет использовано значение из настройки TIME_FORMAT без учета текущего языка.

    timesince

    Форматирует дату как время прошедшее с момента другой даты (например, “4 days, 6 hours”).

    Принимает не обязательный аргумент – дату, используемую как точку отсчета (без аргументов используется текущее время). Например, если blog_date это дата, равная полночи 1 июня 2006, и comment_date равен 08:00, 1 июня 2006, тогда {{ blog_date|timesince:comment_date }} вернет “8 часа”.

    Сравнение абсолютной(с временной зоной) и относительной(без временной зоны) дат вернет пустую строку.

    Минута — самая малая единица измерения, и для дат из будущего, относительно точки сравнения, возвращается “0 минут” .

    timeuntil

    Аналогичен timesince, только определяет время от текущей даты до указанной. Например, если сегодня 1 июня 2006 и conference_date это дата 29 июня 2006, тогда {{ conference_date|timeuntil }} вернет “4 недели”.

    Принимает не обязательный аргумент – дату, используемую как точку отсчета (вместо текущего времени). Если from_date содержи 22 июня 2006, тогда {{ conference_date|timeuntil:from_date }} вернет “1 неделя”.

    Сравнение абсолютной(с временной зоной) и относительной(без временной зоны) дат вернет пустую строку.

    Минута — самая малая единица измерения, и для дат из прошлого, относительно точки сравнения, возвращается “0 минут” .

    title

    Конвертирует строку в заголовок

    Например:

    Если value равно «my first post», вернет «My First Post».

    truncatechars

    Добавлено в Django 1.4.

    Обрезает строку до указанной длины. Обрезанная строка будет оканчиваться троеточием(”…”).

    Аргумент: длинна строки в символах

    Например:

    {{ value|truncatechars:9 }}
    

    Если value равно «Joel is a slug», вернет «Joel i…».

    truncatewords

    Обрезает строку после указанного количества слов.

    Аргумент: количество слов в строке

    Например:

    {{ value|truncatewords:2 }}
    

    Если value равно «Joel is a slug», вернет «Joel is …».

    Переносы строки будут удалены.

    truncatewords_html

    Аналогичен truncatewords, но учитывает наличие HTML тегов. Теги, которые остались открыты в стоке после обрезания, будут немедленно закрыты.

    Этот фильтр менее эффективен чем truncatewords, используйте его только с HTML-текстом.

    Например:

    {{ value|truncatewords_html:2 }}
    

    Если value равно «<p>Joel is a slug</p>», вернет «<p>Joel is …</p>».

    Символы новой строки в содержимом будут сохранены.

    unordered_list

    Принимает вложенный список и возвращает неупорядоченный HTML список – БЕЗ открывающего и закрывающего <ul> тегов.

    Предполагается, что список находится в нужном формате. Например, если var равен [‘States’, [‘Kansas’, [‘Lawrence’, ‘Topeka’], ‘Illinois’]], тогда {{ var|unordered_list }} вернет:

    <li>States
    <ul>
            <li>Kansas
            <ul>
                    <li>Lawrence</li>
                    <li>Topeka</li>
            </ul>
            </li>
            <li>Illinois</li>
    </ul>
    </li>
    

    Заметка: старый, более строгий и подробный формат, так же поддерживается: [‘States’, [[‘Kansas’, [[‘Lawrence’, []], [‘Topeka’, []]]], [‘Illinois’, []]]],

    upper

    Конвертирует строку в верхний регистр

    Например:

    Если value равно «Joel is a slug», будет возвращено «JOEL IS A SLUG».

    urlencode

    Экранирует значение для безопасного использования в URL.

    Например:

    Если value равно «http://www.example.org/foo?a=b&c=d», будет возвращено «http%3A//www.example.org/foo%3Fa%3Db%26c%3Dd».

    Добавлено в Django 1.3.

    Используй не обязательный аргумент, можно указать символы, который не должны быть экранированы.

    Если аргумент не указан, символ ‘/’ предполагается как безопасный символ. Если необходимо экранировать все символы, передайте пустую строку. Например:

    Если value равно «http://www.example.org/», будет возвращено «http%3A%2F%2Fwww.example.org%2F».

    urlize

    Конвертирует URL-ы в тексте в “кликабельные” ссылки.

    Этот тег конвертирует ссылки с префиксами http://, https://, или www.. Например, http://goo.gl/aia1t будет конвертирован, goo.gl/aia1t – нет.

    Так же поддерживаются ссылки состоящие только из домена и заканчивающиеся на один из первоначальных доменов первого уровня (.com, .edu, .gov, .int, .mil, .net, and .org). Например, djangoproject.com будет преобразован.

    Изменено в Django 1.4.

    До Django 1.4, поддерживались только суффиксы .com, .net and .org.

    Ссылки могут быть с завершающей пунктуацией (точка, запятая, закрывающая скобка) и предшествующей пунктуацией (открывающая скобка), urlize все корректно преобразует.

    Ссылки созданные urlize содержат атрибут rel=»nofollow».

    Например:

    Если value равно «Check out www.djangoproject.com», будет выведено «Check out <a href=»http://www.djangoproject.com» rel=»nofollow»>www.djangoproject.com</a>».

    Фильтр urlize принимает не обязательный аргумент autoescape. Если autoescape равен True, текст ссылки и URL будут экранированы с помощью фильтра escape. Значение по-умолчанию для autoescape равно True.

    Примечание

    Если применить urlize к тексту, который содержит HTML, результат будет неверным. Применяйте фильтр только к обычному тексту.

    urlizetrunc

    Преобразует URL-ы в ссылки как и urlize, но обрезает название ссылок длиннее указанного предела.

    Аргумент: Максимальное количество символов в названии ссылки, включая троеточие добавленное при обрезании текста.

    Например:

    {{ value|urlizetrunc:15 }}
    

    Если value равно «Check out www.djangoproject.com», вернет ‘Check out <a href=»http://www.djangoproject.com» rel=»nofollow»>www.djangopr…</a>’.

    Как и urlize, фильтр следует применять к обычному тексту.

    wordcount

    Возвращает количество слов.

    Например:

    Если value равно «Joel is a slug», верент 4.

    wordwrap

    “Оборачивает” слова до указанной длинны строки.

    Аргумент: количество символов в строке

    Например:

    Если value равно Joel is a slug, вернет:

    yesno

    Для true, false и (опционально) None выводит строки “yes”, “no”, “maybe”, или другие, переданные как список значений, разделенный запятыми:

    Например:

    {{ value|yesno:"yeah,no,maybe" }}
    

    Значение

    Аргумент

    Вывод

    True yes
    True«yeah,no,maybe»yeah
    False«yeah,no,maybe»no
    None«yeah,no,maybe»maybe
    None«yeah,no»

    «no» (конвертирует None в False если значение для None не указано)

    Расширяем свое приложение · HonKit

    Мы уже выполнили часть необходимых шагов для создания веб-сайта: мы знаем как создать модель, URL, представление и шаблон. Мы также знаем, как улучшить визуальный дизайн с помощью CSS.

    Время для практики!

    Первое, что нам потребуется в блоге — страница для отображения конкретной записи, верно?

    У нас уже есть модель Post, так что нам не нужно добавлять дополнительный код в файл models.py.

    Создадим в шаблоне ссылку на страницу поста

    Мы начнём с добавления ссылки внутри файла blog/templates/blog/post_list.html. Пока он выглядит следующим образом:

    blog/templates/blog/post_list.html

    {% extends 'blog/base.html' %}
    
    {% block content %}
        {% for post in posts %}
            <div>
                <div>
                    {{ post.published_date }}
                </div>
                <h2><a href="">{{ post.title }}</a></h2>
                <p>{{ post.text|linebreaksbr }}</p>
            </div>
        {% endfor %}
    {% endblock %}
    

    Нам хотелось бы иметь ссылку с заголовка поста в списке на страницу с подробной информацией о посте. Давай изменим <h2><a href="">{{ post.title }}</a></h2>, чтобы получилась ссылка на пост:

    blog/templates/blog/post_list.html

    <h2><a href="{% url 'post_detail' pk=post.pk %}">{{ post.title }}</a></h2>
    

    Самое время разобраться с загадочным {% url 'post_detail' pk=post.pk %}. Как можешь предположить, синтаксис {% %} означает использование тегов шаблонов Django. На этот раз мы используем тот, что создаст для нас URL!

    Параметр post_detail означает, что Django будет искать URL с именем post_detail в файле blog.urls.py.

    А что насчёт pk=post.pk? pk — это сокращение от primary key (первичный ключ). Он уникальным образом определяет каждую запись в базе данных. Поскольку мы не задали первичного ключа в нашей модели Post, Django создал такой ключ за нас (по умолчанию это порядковый номер, то есть 1, 2, 3…) и добавил поле pk к каждой записи блога. Для получения первичного ключа мы напишем post.pk — точно так же, как мы получали значения остальных полей (title, author и т.д.) нашего объекта Post.

    Теперь, когда мы перейдем по адресу http://127.0.0.1:8000/, мы получим ошибку (как и ожидается, поскольку у нас нет прописанного URL и представления для post_detail). Она будет выглядеть следующим образом:

    Создадим URL для страницы поста

    Давай создадим в urls.py URL для представления post_detail!

    Мы хотим, чтобы наш первый пост отображался на странице со следующим URL-адресом: http://127.0.0.1:8000/post/1/

    Давай создадим URL в файле blog/urls.py и укажем Django на представление под названием post_detail, которое будет отображать пост целиком. Добавь строчку path('post/<int:pk>/', views.post_detail, name='post_detail') в файл blog/urls.py. Файл должен выглядеть так:

    blog/urls.py

    from django.urls import path
    from . import views
    
    urlpatterns = [
        path('', views.post_list, name='post_list'),
        path('post/<int:pk>/', views.post_detail, name='post_detail'),
    ]
    

    Фрагмент post/<int:pk>/ определяет шаблон URL-адреса. Сейчас мы его поясним:

    • post/ значит, что после начала строки URL должен содержать слово post и косую черту /. Пока всё в порядке.
    • <int:pk> — эта часть посложнее. Она означает, что Django ожидает целочисленное значение и преобразует его в представление — переменную pk.
    • / — затем нам нужен еще один символ / перед тем, как адрес закончится.

    Славненько, мы добавили новый шаблон URL в файл blog/urls.py! Давай обновим страницу: http://127.0.0.1:8000/. Бууум! Сервер снова перестал работать. Проверь консоль — как и ожидалось, ещё одна ошибка!

    Помнишь, каким должен быть следующий шаг? Конечно: добавить представление!

    Добавим представление для страницы поста

    В этот раз представление получит дополнительный параметр pk. Но как дать нашему представлению знать о нём? Для этого мы определим функцию как def post_detail(request, pk):. Обрати внимание, что мы должны использовать то же имя переменной, что мы выбрали для обработки URL (pk). Пропуск переменной будет неправилен и приведёт к ошибке!

    Теперь мы хотим получить одну конкретную запись из блога. Для этого потребуется использовать QuerySet:

    blog/views.py

    Post.objects.get(pk=pk)
    

    Однако в этом коде есть проблема. Если не существует экземпляра объекта Post с заданным primary key (pk), мы получим страшную ошибку!

    Мы этого не хотим! Однако в Django, конечно, есть средство, которое позволит нам её обойти: get_object_or_404. В случае, если не существует экземпляра объекта Post с заданным pk, мы получим намного более приятную страницу (которая называется Page Not Found 404).

    Хорошая новость состоит в том, что ты можешь сделать свою страницу Page not found. Но для нас сейчас это не самая важная задача, и мы её пропустим.

    Хорошо, пришло время добавить представление в файл views.py!

    В файле blog/urls.py мы создали шаблон URL под названием post_detail, который ссылался на представление под названием views.post_detail. Это значит, что Django ожидает найти функцию-представление с названием post_detail в blog/views.py.

    Нам нужно открыть файл blog/views.py и добавить в него следующий код:

    blog/views.py

    from django.shortcuts import render, get_object_or_404
    

    — рядом с другими строками, начинающимися с from. В конец же файла мы добавим наше новое представление:

    blog/views.py

    def post_detail(request, pk):
        post = get_object_or_404(Post, pk=pk)
        return render(request, 'blog/post_detail.html', {'post': post})
    

    Вот так. Теперь обнови страницу http://127.0.0.1:8000/

    Заработало! Только что произойдёт, если ты попробуешь перейти по ссылке из заголовка записи?

    Ой, нет! Другая ошибка! Но мы уже знаем, как иметь с ней дело, верно? Нам нужно добавить шаблон!

    Создадим шаблон для страницы поста

    Мы создадим файл post_detail.html в директории blog/templates/blog.

    Он должен содержать следующее:

    blog/templates/blog/post_detail.html

    {% extends 'blog/base.html' %}
    
    {% block content %}
        <div>
            {% if post.published_date %}
                <div>
                    {{ post.published_date }}
                </div>
            {% endif %}
            <h2>{{ post.title }}</h2>
            <p>{{ post.text|linebreaksbr }}</p>
        </div>
    {% endblock %}
    

    И снова мы расширяем base.html. В блоке content мы отображаем дату публикации (published_date, если она существует), заголовок и текст. Нам также нужно обсудить пару важных вещей, хорошо?

    {% if ... %} ... {% endif %} — это тег шаблона, который мы можем использовать, если нам нужно что-то проверить (помнишь конструкцию if ... else .. из главы Введение в Python?). В данном случае мы хотим проверить, не пуста ли дата публикации поста — published_date.

    Отлично, можешь перезагрузить страницу и проверить, пропала ли ошибка Page not found.

    Ура! Всё работает!

    Ещё одна вещь: развёртывание!

    Было бы неплохо проверить, что веб-сайт всё ещё будет работать на PythonAnywhere, верно? Давай еще раз проведём развёртывание.

    command-line

    $ git status
    $ git add --all .
    $ git status
    $ git commit -m "Added view and template for detailed blog post as well as CSS for the site."
    $ git push
    

    Затем набери в Bash-консоли PythonAnywhere:

    PythonAnywhere command-line

    $ cd ~/<your-pythonanywhere-domain>.pythonanywhere.com
    $ git pull
    [...]
    

    И нажми Reload на вкладке Web.

    Обновим статические файлы на сервере

    Серверы вроде PythonAnywhere часто обрабатывают статические файлы (например, CSS) не так, как Python-файлы. Так происходит потому, что сервера могут оптимизировать их использование так, чтобы они быстрее загружались. В результате после того, как мы поменяли CSS-файлы, надо дать серверу команду обновить их. Эта команда называется collectstatic.

    Начни с активации virtualenv, если окружение уже не активно (PythonAnywhere использует для этого команду workon. Она работает так же, как source myenv/bin/activate, которую ты используешь на своём компьютере.

    PythonAnywhere command-line

    $ workon <your-pythonanywhere-domain>.pythonanywhere.com
    (ola.pythonanywhere.com)$ python manage.py collectstatic
    [...]
    

    Команда manage.py collectstatic немножко похожа на manage.py migrate. Мы сперва вносим какие-то изменения в наш код, а затем сообщаем Django применить эти изменения — к набору статических файлов на сервере или к базе данных.

    В любом случае, мы теперь готовы перейти по ссылке «Web» page (нажав на кнопку в меню в правом верхнем углу консоли) и кликнуть на Reload, а затем посмотреть на страницу https://subdomain.pythonanywhere.com, где отобразится результат.

    Вот и всё! Поздравляем 🙂

    Создание первого приложения на Django, часть 3 | Документация Django 3.1

    Этот учебник продолжает вас знакомить с Django с места, где мы остановились в Tutorial 2. Мы продолжаем приложение Web-poll и сосредоточимся на создании открытого интерфейса — «представлений».

    Где получить помощь:

    Если у вас возникли проблемы с просмотром этого учебника, перейдите в раздел Получение справки FAQ.

    Быстрый обзор¶

    Представление – это «тип» веб-страницы в приложении Django, которая обычно выполняет определенную функцию и имеет определенный шаблон. Например, в приложении блога у вас могут быть следующие представления:

    • Домашняя страница блога — отображает последние записи.
    • Страница «Детализация» — отдельная страница одной записи.
    • Страница архива на основе года — отображает все месяцы с записями в данном году.
    • Страница архива на основе месяца — отображает все дни с записями в данном месяце.
    • Дневная архивная страница — отображает все записи за данный день.
    • Действия с комментариями — обрабатывает размещение комментариев к данной записи.

    В нашем приложении для опроса будут следующие четыре представления:

    • Главная страница вопросов — отображает последние несколько вопросов.
    • Страница вопроса — отображает текст вопроса, без результатов, но с формой для голосования.
    • Страница результатов вопроса — отображает результаты для конкретного вопроса.
    • Голосования — обрабатывает голосование за определенный выбор в конкретном вопросе.

    В Django веб-страницы и другой контент доставляются по представлениям. Каждое представление представлено функцией Python (или методом в случае представлений на основе классов). Django выберет представление, изучив запрашиваемый URL (точнее, часть URL после имени домена).

    Теперь, находясь в Интернете, вы можете встретить такую красоту, как «ME2/Sites/dirmod.asp?sid=&type=gen&mod=Core+Pages&gid=A6CD4967199A42D9B65B1B». Вам будет приятно узнать, что Django позволяет создавать гораздо более элегантные шаблоны URL.

    Шаблон URL — это общая форма URL, например: /newsarchive/<year>/<month>/.

    Чтобы перейти от URL к представлению, Django использует так называемый URLconfs. URLconf сопоставляет шаблоны URL с представлениями.

    Этот учебник содержит основные инструкции по использованию URLconfs, и вы можете обратиться к Диспетчер URL для получения дополнительной информации.

    Написание представлений¶

    Теперь давайте добавим еще несколько представлений в 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, добавив следующие path() вызовы:

    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'),
    ]
    

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

    Когда кто-то запрашивает страницу с вашего сайта — скажем, «/polls/34/», Django загрузит модуль Python mysite.urls, поскольку на него указывает параметр ROOT_URLCONF. Он находит переменную с именем « urlpatterns« и просматривает шаблоны по порядку. После нахождения соответствия в 'polls/' ``, он убирает соответствующий текст («polls/») и отправляет оставшийся текст - ``"34/" — в „polls.urls“ URLconf для дальнейшей обработки. Там он соответствует '<int:question_id>/', что приводит к вызову представления detail() следующим образом:

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

    Часть question_id=34 взята из <int:question_id>. Использование угловых скобок «захватывает» часть URL и отправляет ее в качестве ключевого аргумента в функцию представления. Часть строки :question_id> определяет имя, которое будет использоваться для идентификации сопоставленного шаблона, а часть <int: — это преобразователь, который определяет, какие шаблоны должны соответствовать этой части пути URL.

    Написание представлений, которые что-то делают¶

    Каждое представление отвечает за выполнение одного из двух действий: возвращение объекта HttpResponse, содержащего ответ для запрашиваемой страницы, или создание исключения, такого как Http404. Остальное зависит от вас.

    Ваше представление может читать записи из базы данных, или нет. Оно может использовать систему шаблонов, такую как Django или стороннюю систему шаблонов Python, или нет. Он может генерировать PDF-файл, выводить XML, создавать ZIP-файл на лету, что угодно, используя любые библиотеки Python, которые вы хотите.

    Все, чего хочет Джанго, это HttpResponse. Или исключение.

    Поскольку это удобно, давайте использовать собственное API базы данных Django, который мы рассмотрели в Tutorial 2. Вот другой вариант в новом представлении index(), который отображает последние 5 вопросов, разделенных запятыми, в соответствии с датой публикации:

    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, создав шаблон, который может использовать представление.

    Сначала создайте каталог с именем templates в вашем каталоге polls. Джанго будет искать там шаблоны.

    Параметр TEMPLATES вашего проекта описывает, как Django будет загружать и отображать шаблоны. Файл настроек по умолчанию настраивает бэкэнд DjangoTemplates, чья опция APP_DIRS установлена в « True«. По соглашению DjangoTemplates ищет подкаталог «templates» в каждом из INSTALLED_APPS.

    В каталоге templates, который вы только что создали, создайте еще один каталог с именем polls, а внутри него создайте файл с именем index.html. Другими словами, ваш шаблон должен быть в polls/templates/polls/index.html. Из-за того, что загрузчик шаблонов app_directories работает так, как описано выше, вы можете ссылаться на этот шаблон в Django как polls/index.html.

    Пространство имен шаблонов

    Теперь мы можем избежать размещения наших шаблонов непосредственно в polls/templates (вместо создания другого подкаталога polls), но на самом деле это будет плохая идея. Django выберет первый найденный шаблон, имя которого совпадает, и если у вас есть шаблон с таким же именем в другом приложении, Django не сможет различить их. Мы должны быть в состоянии указать Django на правильный, и лучший способ убедиться в этом — пространство имен. То есть, помещая эти шаблоны в другой каталог, названный для самого приложения.

    Поместите следующий код в этот шаблон:

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

    Примечание

    Чтобы сделать урок короче, во всех примерах шаблонов используется неполный HTML. В ваших собственных проектах вы должны использовать полные документы HTML.

    Теперь давайте обновим наше представление index в 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.

    Загрузите страницу, указав в браузере «/polls/», и вы увидите маркированный список, содержащий вопрос «What’s up» из Tutorial 2. Ссылка указывает на страницу с подробностями вопроса.

    Сокращение

    render()

    Это очень распространенная идиома: загрузить шаблон, заполнить контекст и вернуть объект HttpResponse с результатом визуализации шаблона. Джанго предоставляет сокращение. Вот полное представление 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)
    

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

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

    Ошибка 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})
    

    Новая концепция: представление вызывает исключение Http404, если вопрос с запрошенным идентификатором не существует.

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

    polls/templates/polls/detail.html¶

    для начала.

    Сокращение

    get_object_or_404()

    Это очень распространенная практика: использовать get() и вызывать Http404, если объект не существует. Джанго предоставляет сокращение функции. Вот представление detail(), переписанное:

    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_object_or_404() вместо того, чтобы автоматически перехватывать исключения ObjectDoesNotExist на более высоком уровне или вызывать через API модели Http404 вместо ObjectDoesNotExist?

    Потому что это связывает уровень модели с уровнем представления. Одна из главных целей Django — поддерживать слабую связь. Некоторая контролируемая связь представлена в модуле django.shortcuts.

    Также есть функция get_list_or_404(), которая работает так же, как get_object_or_404() — за исключением использования filter() вместо get(). Он вызывает Http404, если список пуст.

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

    Вернемся к представлению detail() нашего приложения poll. Учитывая переменную контекста question, вот как может выглядеть шаблон polls/detail.html:

    polls/templates/polls/detail.html¶

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

    Система шаблонов использует синтаксис поиска точек для доступа к переменным. В примере {{ question.question_text }} сначала Django выполняет поиск в словаре по объекту question. В противном случае он пытается найти атрибут, который работает, в данном случае. Если поиск атрибута не удался, он попытался бы выполнить поиск по индексу списка.

    Вызов метода происходит в цикле {% for %}. question.choice_set.all интерпретируется как код Python question.choice_set.all(), который возвращает итерацию объектов Choice и подходит для использования в теге {% for %}.

    Смотрите руководство по шаблонам, чтобы узнать больше о шаблонах.

    Удаление жестко закодированных URL-адресов в шаблонах¶

    Помните, когда мы писали ссылку на вопрос в шаблоне polls/index.html, она была частично жестко закодирована следующим образом:

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

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

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

    Это работает с помощью поиска определенного URL, указанного в модуле polls.urls. Вы можете увидеть, как определен URL-адрес „detail“, ниже:

    ...
    # the 'name' value as called by the {% url %} template tag
    path('<int:question_id>/', views.detail, name='detail'),
    ...
    

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

    ...
    # added the word 'specifics'
    path('specifics/<int:question_id>/', views.detail, name='detail'),
    ...
    

    Пространства имен URL¶

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

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

    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'),
    ]
    

    Теперь измените ваш шаблон polls/index.html:

    polls/templates/polls/index.html¶

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

    для указания на пространство имен:

    polls/templates/polls/index.html¶

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

    Если вам удобно писать представления, прочитайте часть 4 этого урока, чтобы узнать основы обработки форм и общих представлений.

    Навигация в шаблонах Django / Хабр

    Наверно в каждом проекте есть система навигации — пользователи кликают по ссылкам, менюшкам и нам(разработчикам\дизайнерам\верстальщикам) надо как-то «подсвечивать» страницу\ссылку на которой сейчас находится пользователь.

    Предоставляю не тривиальное решение очень тривиальной задачи при разработки навигации в Django проектах.


    Для не терпеливых можно сразу взглянуть на проект на github.

    Самое тривиальное решение

    В каждой вьюхе в контексте передаем некую переменную, пусть будет «location» и потом беспощадно хардкодим:

    <ul>
      <li {% if location=='random_page' %} {% endif %}>
        <a href="{% url 'random_page' %}">
          {% trans 'random page' %}
        </a>
      </li>
    </ul>
    

    Получается — к каждой ссылки уникальное значение «location», что порождает очень много лишнего кода, когда ссылок\вьюх становится много практически не возможно запомнить какой «location» к какой ссылке, а так же верстальщик может быть крайне не доволен необходимостью вникать в логику питоновских вьюх и какое значение от куда попадает в контекст.

    Можно передавать «location» такой же как именная ссылка данной вьюхи и навигация станет слегка наглядней.

    Реализация через простой «template filter»

    собственно фильтр:

    from django import template
    
    
    register = template.Library()
    
    
    def active(url, request):
        if url == request.get_full_path():
            return True
        else:
            return False
    
    
    register.filter('active', active)
    

    дальше в шаблоне:

    {% load active %}
    
    <ul>
      {% url 'random_page' as random_page %}
      <li {% if random_page|active:request %} {% endif %}>
        <a href="{{ random_page }}">
          {% trans 'random page' %}
        </a>
      </li>
    </ul>
    

    Передавать переменные с вьюх уже не нужно, можно заменить сравнение на .startswith() или вовсе на регулярки и добавить поддержу меню, например светить ссылку на «/menu/» когда пользователь находится на странице «/menu/submenu/». Но рутина никуда не делась…

    Мои велосипеды — django-activeurl

    Рутинные действия напрочь отсутствуют, а именно:

    {% load activeurl %}
    
    {% activeurl %}
      <ul>
        <li>
          <a href="{% url 'random_page' %}">
            {% trans 'random page' %}
          </a>
        </li>
      </ul>
    {% endactiveurl %}
    

    немного магии…

    <ul>
      <li>
        <a href="/random_page/">
          random page
        </a>
      </li>
    </ul>
    

    Установка как и у всех питоновских батареек:

    pip install django-activeurl
    

    Все нюансы описаны тут.

    Теперь, немного о том как всё это работает — из переданного html с помощью lxml строится дерево, в нем идет поиск HTML элементов которые надо подсветить(по умолчанию «li»), потом в этом тэге берутся все ссылки и их параметр «href» сравнивается с «request.get_full_path()».

    Реализованные фичи:

    Поменьше всем рутинных задач при разработке!

    Использование Jinja2 с Django (начиная с 1.8)

    На ресурсе Medium Corporation пользователь под ником Samu делится опытом использования Jinja2.

    По его словам ранее он использовал Jinja2 в своих проектах, созданных с помощью Flask. Но затем решил использовать Jinja2 с Django для потенциального повышения производительности (в 10-20 раз быстрее по сравнению с шаблонами Django) и взаимодействия с Nunjucks.

    Samu делится опытом с людьми, которые уже знакомы с данными технологиями, а его статья призвана немного раскрыть и упростить шаги.

    Если же вы только начинаете с Django, то он рекомендует начать с замечательного урока

    по данной сылке

    . Так же можете посмотреть несколько простых инструкций для Jinja2 от Django

    здесь

    .

    Итак, приступим.

    Сначала установите и настройте Jinja2
    pip install Jinja2
    

    и не забудьте добавить его в файл needs.txt. Затем добавьте следующие настройки движка шаблонов в переменную TEMPLATES в settings.py

    {
       ‘BACKEND’: ‘django.template.backends.jinja2.Jinja2’,
       ‘DIRS’: [],
       ‘APP_DIRS’: True,
       ‘OPTIONS’: {
         ‘environment’: ‘your-app.jinja2.environment’
       },
     }
    

    Итак, все настройки шаблона выглядят примерно так:

    TEMPLATES = [
     {
       ‘BACKEND’: ‘django.template.backends.jinja2.Jinja2’,
       ‘DIRS’: [],
       ‘APP_DIRS’: True,
       ‘OPTIONS’: {
         ‘environment’: ‘your-app.jinja2.environment’
       },
     },
     {
       ‘BACKEND’: ‘django.template.backends.django.DjangoTemplates’,
       ‘DIRS’: [],
       ‘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’,
         ],
       },
     },
    ]
    

    Не забудьте также изменить переменную среды параметров Jinja2 на правильное имя приложения (измените «your-app» на то, как называется папка вашего приложения).

    Среда параметров позволяет нам использовать определенные функции в шаблонах, которые настраиваются дальше. Создайте файл jinja2.py в папке вашего приложения (там же, где был файл settings.py) и добавьте следующее:

    from django.contrib.staticfiles.storage import staticfiles_storage
    from django.urls import reverse
    from jinja2 import Environment
    def environment(**options):
        env = Environment(**options)
        env.globals.update({
            ‘static’: staticfiles_storage.url,
            ‘url’: reverse,
        })
     return env
    

    Это позволяет нам использовать теги шаблонов Django, такие как {% url ‘index’%} или {% static ‘path / to / static / file.js’%} в наших шаблонах Jinja2. Как видите, эти теги шаблонов используют фактические функции, предоставляемые Django. Следуя Jinja2-способу вызова функций в шаблоне, вы можете использовать их следующим образом:

    В Django:

    {% url ‘index’ variable %}
    

    что эквивалентно в Jinja2:

    {{url(‘index’, args=[variable])}}
    

    И для именованных переменных вы можете использовать:

    {{url('index', kwargs={'variable_key':variable}}}
    

    В Django:

    {% static ‘path’ %}
    

    что эквивалентно

    {{ static(‘path’)}}
    

    Как вы, наверное, уже заметили, вы можете в основном добавлять любые функции в среду Jinja2, добавляя их в файл jinja2.py, для дальнейшего использования в шаблонах.

    Итоговые установочные папки

    После того, как вы правильно выполните настройки, в дальнейшем можно просто создать папку Jinja2 в любом месте, где будет создана папка шаблонов. Работать должно автоматически, так как Django — это довольно хорошая среда. Наличие обоих шаблонов Django и Jinja2 позволяет вам гибко использовать оба. Например, у вас может быть панель администратора Django, и различные плагины для работы, которые используют шаблоны Django. Обязательно прочитайте документацию Jinja2, чтобы узнать больше.

    Ниже представлен пример того, как одна структура папок приложения может выглядеть для проекта:

    основные операции Django, работа с Django

    В Python очень много полезных функций, библиотек и других элементов, перечислить которые в одном материале очень сложно. Мы поделимся базовой шпаргалкой по Python, которая ориентирована на создание веб-приложений с фреймворком Django. Сохраняйте статью в закладки, чтобы не потерять!

    Этот набор инструкций напомнит вам об основных операциях с Django, если вы работаете над веб-проектом. Сюда входят такие действия, как установка Django, запуск проекта, работа с моделями, создание домашней страницы, использование шаблонов и создание учётных записей пользователей.

    Шпаргалка предназначена для тех, кто уже знаком с Python, понимает, что такое виртуальное окружение, и имеет начальные знания о веб-разработке.

    Что такое Django?

    Django — веб-фреймворк для создания интерактивных веб-сайтов на Python. В Django вы определяете тип данных, с которыми ваш сайт должен работать, а затем указываете, как пользователи могут взаимодействовать с этими данными. Все описанные ниже действия актуальны для Django 3.0.

    Установка Django

    Лучше установить Django в виртуальном окружении — virtualenv или pipenv, где ваш проект будет изолирован от других. Большинство команд, приведённых ниже, предполагают, что вы работаете в виртуальной среде.

    Создать виртуальную среду

    venv:

    $ python –m venv ll_env

    pipenv:

    $ pipenv --python 3.8

    Активировать среду

    venv, macOS and Linux:

    $ source ll_env/bin/activate

    venv, Windows:

    > ll_env\Scripts\activate

    pipenv:

    $ pipenv shell

    Установить Django в активную среду

    venv:

    (ll_env)$ pip install Django

    pipenv:

    pipenv install Django

    Создание проекта

    Чтобы начать работу, мы создадим новый проект и базу данных, а затем запустим веб-сервер. Во всех примерах ниже проект будет называться learning_log.

    Создать новый проект

    $ django-admin startproject learning_log .

    Создать базу данных

    $ python manage.py migrate

    Посмотреть проект

    После выполнения этой команды вы можете просмотреть проект по адресу http://localhost:8000/.

    $ python manage.py runserver

    Создать новое приложение

    Проект Django состоит из одного или нескольких приложений.

    $ python manage.py startapp learning_logs

    Перезапуск сервера разработки

    Если вы вносите изменения в свой проект, но ничего не происходит, попробуйте перезапустить сервер:

    $ python manage.py runserver

    Работа с моделями

    Данные в проекте Django представлены в виде набора моделей — объектов Python, определяющих структуру хранения этих данных.

    Определение модели

    Чтобы определить модель для вашего приложения, измените файл models.py, созданный в папке приложения. Метод __str __() сообщает Python, как отображать экземпляр модели в строковом представлении. Django использует этот механизм для отображения объектов в формах.

    from django.db import models
    class Topic(models.Model):
        """Тема, которую изучает пользователь."""
        text = models.CharField(max_length=200)
        date_added = models.DateTimeField(
            auto_now_add=True)
    
     def __str__(self):
         return self.text

    Активация модели

    Для использования модели приложение должно быть добавлено в список INSTALLED_APPS, который хранится в файле settings.py проекта.

    INSTALLED_APPS = [
        # Мои приложения.
        'learning_logs',
        # Дефолтные приложения Django.
        'django.contrib.admin',
    ]

    Миграция базы данных

    База данных должна быть модифицирована для хранения данных модели. Вам нужно будет запускать эти команды каждый раз, когда вы создаете новую модель или модифицируете существующую модель.

    $ python manage.py makemigrations learning_logs
    
    $ python manage.py migrate

    Создание суперпользователя

    Суперпользователь — это учётная запись с доступом ко всем компонентам проекта.

    $ python manage.py createsuperuser

    Регистрация модели

    Вы можете зарегистрировать свою модель в панели администратора Django, чтобы упростить работу с данными в проекте. Для этого измените файл admin.py. Панель администратора находится по адресу http://localhost:8000/admin/.

    from django.contrib import admin
    from .models import Topic
    
    admin.site.register(Topic)

    Создание новой модели

    Новая модель может использовать существующую модель. Атрибут ForeignKey устанавливает связь между экземплярами двух связанных моделей. Обязательно мигрируйте базу данных после добавления новой модели в ваше приложение.

    Определение модели с внешним ключом:

    class Entry(models.Model):
        topic = models.ForeignKey(Topic,
            on_delete=models.CASCADE)
        text = models.TextField()
        date_added = models.DateTimeField(
            auto_now_add=True)
    
       def __str__(self):
            return f"{self.text[:50]}..."

    Создание простой домашней страницы

    Пользователи взаимодействуют с проектом через веб-страницы. Мы создадим простую домашнюю страницу без данных. Любой странице обычно нужен URL, представление (view) и шаблон (template). Представление — функция Python, которая принимает HTML-запрос и возвращает ответ на него. Шаблон — специальный набор инструкций, позволяющий динамически генерировать HTML.

    Сопоставление URL-адресов проекта

    Основной файл проекта urls.py сообщает Django, где найти файлы urls.py, связанные с каждым приложением в проекте.

    from django.contrib import admin
    from django.urls import path, include
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('', include('learning_logs.urls')),
    ]

    Сопоставление URL-адресов приложения

    Файл urls.py в приложении сообщает Django, какое представление использовать для каждого URL-адреса в этом приложении. Вам нужно создать этот файл самостоятельно и сохранить его в папке приложения.

    from django.urls import path
    from . import views
    
    app_name = 'learning_logs'
    urlpatterns = [
        # Домашняя страница.
        path('', views.index, name='index'),
    ]

    Создание простого представления

    Представление берёт информацию из запроса и отправляет данные в браузер, часто через шаблон. Функции представления хранятся в файле views.py. Ниже приведена простая функция, которая не извлекает какие-либо данные, но использует для отображения домашней страницы шаблон .

    from django.shortcuts import render
    
    def index(request):
        """Домашняя страница."""
        return render(request,
            'learning_logs/')

    Написание простого шаблона

    Шаблон устанавливает структуру страницы. Создайте папку с именем templates в директории проекта. Внутри templates создайте ещё одну папку с тем же именем, как у приложения. Здесь должны быть сохранены все файлы шаблонов. Шаблон домашней страницы будет сохранён как learning_logs/templates/learning_logs/.

    Наследование шаблонов

    Многие элементы повторяются на каждой странице сайта или же в одном из разделов. Написав один родительский шаблон для сайта или раздела, вы можете легко установить внешний вид всего сайта.

    Родительский шаблон

    Родительский шаблон определяет общие элементы для набора страниц, а также уникальные блоки для отдельных страниц.

    <p>
      <a href="{% url 'learning_logs:index' %}">
        Learning Log
      </a>
    </p>
    
    {% block content %}{% endblock content %}

    Дочерний шаблон

    Дочерний шаблон использует тег {% extends %} для извлечения структуры родительского шаблона. Затем он переопределяет содержимое для блоков, указанных в родительском шаблоне.

    {% extends 'learning_logs/base.html' %}
    
    {% block content %}
    
      <p>
        Learning Log helps you keep track of your learning, for any topic you're learning about.
      </p>
    
    {% endblock content %}

    Отступы в шаблоне

    Отступы в Python обычно отбиваются четырьмя пробелами. В шаблонах вы часто можете встретить отступы в два пробела, потому что вложенность кода как правило более глубокая.

    Создание страницы с данными

    Большинство страниц в проекте должны показывать данные, относящиеся к текущему пользователю.

    Параметры URL

    URL-адрес часто принимает параметр, сообщающий ему, к каким данным из базы данных обращаться. Показанный ниже шаблон URL ищет идентификатор конкретной темы и присваивает его параметру topic_id.

    urlpatterns = [
        # --snip--
        path('topics/<int:topic_id>/', views.topic,
            name='topic'),
    ]

    Использование данных в представлении

    Представление использует параметр из URL, чтобы извлечь правильные данные из базы данных. В этом примере представление отправляет контекстный словарь в шаблон, содержащий данные, которые должны отображаться на странице. Вы можете импортировать любую модель, которую используете.

    def topic(request, topic_id):
        """Показывает тему и все её записи."""
        topic = Topic.objects.get(id=topic_id)
        entries = topic.entry_set.order_by(
            '-date_added')
        context = {
            'topic': topic,
            'entries': entries,
        }
        return render(request,
            'learning_logs/topic.html', context)

    Использование данных в шаблоне

    Данные, передаваемые в словаре-контексте, доступны в шаблоне. Доступ к этим данным осуществляется с помощью переменных шаблона, которые обозначены двойными фигурными скобками. Вертикальная линия после шаблонной переменной указывает на фильтр. В нашем примере фильтр с именем date форматирует объекты даты, а фильтр разрыва строки правильно отображает абзацы на веб-странице.

    {% extends 'learning_logs/base.html' %}
    
    {% block content %}
    
      <p>Topic: {{ topic }}</p>
    
      <p>Entries:</p>
      <ul>
      {% for entry in entries %}
        <li>
        <p>
          {{ entry.date_added|date:'M d, Y H:i' }}
        </p>
        <p>
          {{ entry.text|linebreaks }}
        </p>
        </li>
      {% empty %}
        <li>There are no entries yet.</li>
      {% endfor %}
      </ul>
    
    {% endblock content %}

    Django Shell

    Вы можете работать с проектом Django из командной строки. Это полезно для выполнения запросов и тестирования фрагментов кода.

    Начать сеанс оболочки

    $ python manage.py shell

    Доступ к данным из проекта

    >>> from learning_logs.models import Topic
    >>> Topic.objects.all()
    [<Topic: Chess>, <Topic: Rock Climbing>]
    >>> topic = Topic.objects.get(id=1)
    >>> topic.text
    'Chess'

    Пользователи и формы

    Большинство веб-приложений позволяют посетителям создавать учётные записи. Это позволяет пользователям работать с собственными данными. Некоторые из этих данных могут быть конфиденциальными, а некоторые — общедоступными. Формы Django позволяют пользователям вводить и изменять свои данные.

    Учётные записи пользователей

    Учётные записи пользователей можно обрабатывать приложением — ниже оно создаётся под названием users. Пользователи должны иметь возможность зарегистрироваться, войти и выйти из аккаунта. Django автоматизирует большую часть этих действий.

    Создание приложения users

    После создания приложения обязательно добавьте его в INSTALLED_APPS в файле settings.py проекта.

    $ python manage.py startapp users

    Добавление URL-адресов приложения users

    Добавьте эти строки в файл urls.py проекта, чтобы включить в проект URL-адреса приложения users.

    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('users/', include('users.urls')),
        path('', include('learning_logs.urls')),
    ]

    Использование форм в Django

    Существует несколько способов создания форм и работы с ними. Вы можете использовать установки Django по умолчанию или настроить свои формы. Наиболее простой способ настроить ввод данных, основанных на ваших моделях — использование класса ModelForm. ModelForm автоматически создаёт форму на основе полей модели.

    Создание URL для входа, выхода и регистрации

    Пользователи смогут войти, выйти и зарегистрироваться на сайте. Создайте новый файл urls.py в папке приложения users.

    from django.urls import path, include
    from . import views
    
    app_name = 'users'
    urlpatterns = [
        # Дефолтные url для авторизации.
        path('', include(
            'django.contrib.auth.urls')),
        # Страница авторизации.
        path('register/', views.register,
            name='register'),
    ]

    Шаблон входа

    Вид входа в систему предоставляется по умолчанию, но вам необходимо указать свой собственный шаблон входа. В примере ниже шаблон отображает простую форму входа и показывает основные сообщения об ошибках. Создайте папку templates в директории приложения users, а внутри templates — папку registration. Сохраните файл как login.html.

    Тег {% csrf_token %} помогает предотвратить CSRF-атаки с помощью форм. Элемент {{form.as_p}} отображает форму входа по умолчанию в формате абзаца. Элемент <input> с именем next перенаправляет пользователя на домашнюю страницу после успешного входа в систему.

    {% extends "learning_logs/base.html" %}
    
      {% block content %}
        {% if form.errors %}
        <p>
          Your username and password didn't match. Please try again.
        </p>
        {% endif %}
    
      <form method="post"
          action="{% url 'users:login' %}">
    
        {% csrf token %}
        {{ form.as_p }}
        <button name="submit">Log in</button>
    
        <input type="hidden" name="next"
            value="{% url 'learning_logs:index' %}"/>
    
      </form>
    
    {% endblock content %}

    Отображение текущего статуса входа

    Вы можете изменить шаблон base.html, чтобы показать, вошёл ли пользователь на сайт в данный момент, и предоставить ссылку на страницы входа и выхода. Django делает объект user доступным для каждого шаблона.

    Тег user.is_authenticated позволяет вам показать конкретный контент пользователям в зависимости от того, вошли они в систему или нет. Свойство {{user.username}} приветствует пользователей, которые вошли в систему. Те же, кто не вошёл в систему, увидят ссылки для регистрации или входа.

    <p>
      <a href="{% url 'learning_logs:index' %}">
        Learning Log
      </a>
      {% if user.is_authenticated %}
        Hello, {{ user.username }}.
        <a href="{% url 'users:logout' %}">
          Log out
        </a>
      {% else %}
        <a href="{% url 'users:register' %}">
          Register
        </a> -
        <a href="{% url 'users:login' %}">
          Log in
        </a>
      {% endif %}
    
    </p>
    
    {% block content %}{% endblock content %}

    Шаблон logged_out

    Выход из системы по умолчанию отображается с помощью шаблона logged_out.html, который необходимо сохранить в папке users/templates/registration.

    {% extends "learning_logs/base.html" %}
    {% block content %}
      <p>
      You have been logged out. Thank you
      for visiting!
      </p>
    {% endblock content %}

    Регистрация пользователей

    Представление для регистрации должно отображать пустую форму регистрации при первом запросе страницы, а затем обработать заполненные поля. Успешная регистрация сохраняет данные пользователя, и затем выполняется вход в систему и перенаправление на домашнюю страницу.

    from django.shortcuts import render, redirect
    from django.contrib.auth import login
    from django.contrib.auth.forms import \
            UserCreationForm
    
    def register(request):
        """Регистрация нового пользователя."""
        if request.method != 'POST':
            # Отобразить пустую форму регистрации.
            form = UserCreationForm()
        else:
            # Обработать заполненную форму.
            form = UserCreationForm(
                data=request.POST)
    
            if form.is_valid():
                new_user = form.save()
    
                # Вход в систему, переход на дом.страницу.
                login(request, new_user)
                return redirect(
                    'learning_logs:index')
    
        # Отобразить пустую форму или сообщение об ошибке.
        context = {'form': form}
        return render(request,
            'registration/register.html', context)

    Шаблон регистрации

    Шаблон register.html отображает поля формы регистрации в виде списка тегов <p>.

    {% extends 'learning_logs/base.html' %}
    
    {% block content %}
    
      <form method='post'
          action="{% url 'users:register' %}">
    
        {% csrf_token %}
        {{ form.as_p }}
    
        <button name='submit'>Register</button>
        <input type='hidden' name='next'
            value="{% url 'learning_logs:index' %}"/>
    
      </form>
    
    {% endblock content %}

    Данные пользователей

    У всех пользователей есть данные, которые относятся только к ним. Любая модель, подключенная напрямую к пользователю, нуждается в поле, связывающем экземпляры модели с конкретным пользователем.

    Создание темы, принадлежащей пользователю

    Чтобы связать данные с пользователем, импортируйте модель User и добавьте её в качестве внешнего ключа в модель данных.

    После изменения модели вам нужно будет мигрировать базу данных и установить user ID для каждого существующего пользователя.

    from django.db import models
    from django.contrib.auth.models import User
    
    class Topic(models.Model):
        """Тема, которую просматривает пользователь."""
        text = models.CharField(max_length=200)
        date_added = models.DateTimeField(
            auto_now_add=True)
        owner = models.ForeignKey(User,
            on_delete=models.CASCADE)
    
    def __str__(self):
        return self.text

    Запрос данных для текущего пользователя

    Объект запроса имеет атрибут user в своём представлении. Вы можете использовать этот атрибут для получения данных пользователя — их извлекает метод filter().

    topics = Topic.objects.filter(
        owner=request.user)

    Ограничение доступа незарегистрированным пользователям

    Некоторые страницы показываются только зарегистрированным пользователям. Представления для этих страниц могут быть защищены декоратором @login_required. Любое такое представление будет автоматически перенаправлять незарегистрированных пользователей на соответствующую страницу. Вот пример файла views.py:

    from django.contrib.auth.decorators import \
        login_required
    
    # --snip--
    
    @login_required
    def topic(request, topic_id):
        """Показать тему и все её записи."""

    Установка URL перенаправления

    Декоратор @login_required отправляет неавторизованных пользователей на страницу входа. Добавьте следующую строку в файл settings.py, чтобы Django знал, как найти страницу входа.

    LOGIN_URL = 'users:login'

    Предотвращение случайного доступа

    Некоторые страницы отображают данные на основе параметров URL. Вы можете проверить, что текущий пользователь имеет права на просмотр текущих данных, и вернуть ошибку 404, если это не так.

    from django.http import Http404
    # --snip--
    
    @login_required
    def topic(request, topic_id):
        """Показать тему и все её записи."""
        topic = Topics.objects.get(id=topic_id)
        if topic.owner != request.user:
            raise Http404
    # --snip--

    Формы для редактирования данных

    С Django можно создать форму с существующими данными пользователя и возможностью изменять и сохранять их.

    Создание формы с исходными данными

    Параметр instance позволяет указать начальные данные для формы.

    form = EntryForm(instance=entry)

    Изменение данных перед сохранением

    Аргумент commit = False позволяет вносить изменения перед записью в базу данных.

    new_topic = form.save(commit=False)
    new_topic.owner = request.user
    new_topic.save()

    ⌘⌘⌘

    Django — отличный фреймворк, и мы привели лишь малую часть базовых операций в нём. Если вы хотите поэкспериментировать с Django на настоящем сервере — попробуйте наши Облачные VPS с готовым шаблоном Django и почасовой оплатой от 37 копеек. После заказа сервера Django будет готов к работе уже через минуту.

    Пишите в комментариях, шпаргалки по каким языкам или фреймворкам вы хотели бы видеть в нашем блоге.


    Шпаргалка основана на материалах сайта ehmatthes.github.io.

    Написание вашего первого приложения Django, часть 3 | Документация Django

    Этот учебник начинается с того места, где остановился Урок 2. Мы
    продолжения веб-опроса и сосредоточимся на создании общедоступных
    интерфейс — «просмотры».

    Где получить помощь:

    Если у вас возникли проблемы с прохождением этого руководства, перейдите по ссылке
    раздел Получение помощи в FAQ.

    Обзор¶

    Представление — это «тип» веб-страницы в вашем приложении Django, которая обычно обслуживает
    конкретная функция и имеет определенный шаблон.Например, в блоге
    приложения, у вас могут быть следующие представления:

    • Домашняя страница блога — отображает несколько последних записей.
    • Страница «сведений» о записи — страница с постоянной ссылкой для одной записи.
    • Страница архива по годам — ​​отображает все месяцы с записями в
      данный год.
    • Страница архива по месяцам — отображает все дни с записями в
      данный месяц.
    • Страница архива по дням — отображает все записи за данный день.
    • Действие с комментариями — обрабатывает добавление комментариев к данной записи.

    В нашем приложении для опроса у нас будет четыре представления:

    • Страница «Указатель» вопросов — отображает несколько последних вопросов.
    • Страница «Детали» вопроса — отображает текст вопроса без результатов, но
      с формой для голосования.
    • Страница «Результаты» вопроса — отображает результаты по конкретному вопросу.
    • Действие голосования — обрабатывает голосование за определенный выбор в конкретном
      вопрос.

    В Django веб-страницы и другой контент доставляются с помощью представлений.Каждый вид
    представлен функцией Python (или методом в случае представлений на основе классов).
    Django выберет представление, проверив запрошенный URL (если быть точным,
    часть URL после имени домена).

    Сейчас в сети вы наверняка встречали таких красот, как
    ME2 / Сайты / dirmod.htm? Sid = & type = gen & mod = Core + Pages & gid = A6CD4967199A42D9B65B1B .
    Вам будет приятно узнать, что Django позволяет нам намного элегантнее
    URL-шаблонов , чем это.

    Шаблон URL-адреса — это общая форма URL-адреса, например:
    / архив новостей / <год> / <месяц> / .

    Для перехода от URL к представлению Django использует так называемые «URLconfs». А
    URLconf сопоставляет шаблоны URL-адресов с представлениями.

    В этом руководстве представлены базовые инструкции по использованию URLconfs, и вы можете
    обратитесь к диспетчеру URL-адресов для получения дополнительной информации.

    Написание дополнительных просмотров¶

    Теперь давайте добавим еще несколько просмотров к polls / views.py .Эти взгляды
    немного отличается, потому что они принимают аргумент:

    Деталь

     def (запрос, question_id):
        return HttpResponse ("Вы просматриваете вопрос% s."% question_id)
    
    результаты def (запрос, идентификатор_вопроса):
        response = "Вы просматриваете результаты вопроса% s."
        вернуть HttpResponse (ответ% question_id)
    
    def голосование (запрос, вопрос_ид):
        return HttpResponse ("Вы голосуете по вопросу% s."% question_id)
     

    Подключите эти новые взгляды к опросам .urls , добавив следующие
    путь () звонки:

     из пути импорта django.urls
    
    из . импорт просмотров
    
    urlpatterns = [
        # пример: / polls /
        путь ('', views.index, name = 'index'),
        # пример: / polls / 5 /
        путь (' /', views.detail, name = 'detail'),
        # пример: / polls / 5 / results /
        путь (' / results /', views.results, name = 'results'),
        # пример: / polls / 5 / vote /
        путь (' / vote /', views.vote, name = 'vote'),
    ]
     

    Взгляните в своем браузере на «/ polls / 34 /».Будет запущена деталь ()
    метод и отобразите любой идентификатор, который вы укажете в URL-адресе. Пытаться
    «/ Polls / 34 / results /» и «/ polls / 34 / vote /» тоже — они будут отображать
    заполнитель результатов и страниц голосования.

    Когда кто-то запрашивает страницу с вашего веб-сайта — скажем, «/ polls / 34 /», Django
    загрузит модуль Python mysite.urls , поскольку на него указывает
    ROOT_URLCONF настройка. Он находит переменную с именем urlpatterns
    и просматривает шаблоны по порядку.Найдя совпадение в 'polls /' ,
    он удаляет соответствующий текст ( "polls /" ) и отправляет оставшийся текст —
    "34 /" — в URLconf polls.urls для дальнейшей обработки. Вот оно
    соответствует ' /' , что приводит к вызову представления detail ()
    вот так:

    Деталь

     (request = , question_id = 34)
     

    Часть question_id = 34 происходит от .Использование угла
    скобки «захватывают» часть URL-адреса и отправляют ее в качестве аргумента ключевого слова в
    функция просмотра. Часть строки : question_id> определяет имя, которое
    будет использоваться для идентификации совпадающего шаблона, а часть является
    конвертер, который определяет, какие шаблоны должны соответствовать этой части пути URL.

    Напишите представления, которые действительно что-то делают¶

    Каждое представление отвечает за одно из двух: возврат
    HttpResponse объект, содержащий содержимое для
    запрашиваемая страница или возникает исключение, например Http404
    остальное зависит от вас.

    Ваше представление может читать записи из базы данных или нет. Он может использовать шаблон
    система, такая как Django, или сторонняя система шаблонов Python, или нет.
    Он может генерировать файл PDF, выводить XML, создавать ZIP-файл на лету, что угодно
    вы хотите, используя любые библиотеки Python, которые вам нужны.

    Все, что нужно Django, - это HttpResponse . Или исключение.

    Так как это удобно, давайте воспользуемся собственным API базы данных Django, который мы рассмотрели
    в Уроке 2.Вот один удар по новому индексу ()
    представление, в котором отображаются последние 5 вопросов опроса в системе, разделенные
    запятых, согласно дате публикации:

     из django.http import HttpResponse
    
    из .models import Вопрос
    
    
    def index (запрос):
        latest_question_list = Question.objects.order_by ('- pub_date') [: 5]
        output = ',' .join ([q.question_text для q в latest_question_list])
        return HttpResponse (вывод)
    
    # Оставить остальные просмотры (детали, результаты, голосование) без изменений
     

    Но здесь есть проблема: дизайн страницы жестко запрограммирован в представлении.Если
    если вы хотите изменить внешний вид страницы, вам придется отредактировать этот код Python.
    Итак, давайте воспользуемся системой шаблонов Django, чтобы отделить дизайн от Python с помощью
    создание шаблона, который может использовать представление.

    Сначала создайте каталог с именем templates в своем каталоге polls .
    Django будет искать там шаблоны.

    Параметр TEMPLATES вашего проекта описывает, как Django будет загружаться и
    шаблоны рендеринга. Файл настроек по умолчанию настраивает DjangoTemplates
    бэкэнд, для которого параметр APP_DIRS установлен в
    Истинно .По соглашению DjangoTemplates ищет «шаблоны»
    подкаталог в каждом из INSTALLED_APPS .

    В только что созданном каталоге шаблонов создайте еще один
    каталог под названием polls , и в нем создайте файл с именем
    index.html . Другими словами, ваш шаблон должен быть по адресу
    опрос / шаблоны / опросы / index.html . Из-за того, как app_directories
    загрузчик шаблонов работает, как описано выше, вы можете обратиться к этому шаблону в
    Django as опрос / index.html .

    Расстояние между шаблонами

    Теперь мы, , могли бы, , уйти, поместив наши шаблоны прямо в
    опросов / шаблонов (вместо создания еще одного подкаталога опросов ),
    но на самом деле это было бы плохой идеей. Django выберет первый шаблон
    он находит, чье имя совпадает, и если у вас был шаблон с таким же именем
    в другом приложении Django не сможет различить
    их. Нам нужно указать Django на правильный, а лучший
    способ убедиться в этом - , поместив имён.То есть, поставив те
    шаблоны внутри еще один каталог , названный по имени самого приложения.

    Поместите в этот шаблон следующий код:

    опросы / шаблоны / опросы / index.html¶

     {% if latest_question_list%}
        
    {% еще %}
        

    Нет доступных опросов.

    {% endif%}

    Примечание

    Чтобы сделать руководство короче, все примеры шаблонов используют неполный HTML.В
    в ваших собственных проектах вам следует использовать полные HTML-документы.

    Теперь давайте обновим наш индекс , представление в polls / views.py , чтобы использовать шаблон:

     из django.http import HttpResponse
    из загрузчика импорта django.template
    
    из .models import Вопрос
    
    
    def index (запрос):
        latest_question_list = Question.objects.order_by ('- pub_date') [: 5]
        template = loader.get_template ('опросы / index.html')
        context = {
            'latest_question_list': latest_question_list,
        }
        вернуть HttpResponse (template.рендеринг (контекст, запрос))
     

    Этот код загружает шаблон с именем polls / index.html и передает ему
    контекст. Контекст - это словарь, отображающий имена переменных шаблона в Python.
    объекты.

    Загрузите страницу, указав в браузере «/ polls /», и вы должны увидеть
    bulleted-list, содержащий вопрос «Что происходит?» из Руководства 2. Ссылка указывает на страницу с подробными сведениями о вопросе.

    Ярлык:

    render ()

    Это очень распространенная идиома для загрузки шаблона, заполнения контекста и возврата
    HttpResponse объект с результатом рендеринга
    шаблон.Django предоставляет ярлык. Вот полное представление index () ,
    переписано:

     из django.shortcuts import render
    
    из .models import Вопрос
    
    
    def index (запрос):
        latest_question_list = Question.objects.order_by ('- pub_date') [: 5]
        context = {'latest_question_list': latest_question_list}
        возврат рендеринга (запрос, 'polls / index.html', контекст)
     

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

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

    Вызывает ошибку 404¶

    А теперь перейдем к просмотру деталей вопроса - странице, на которой отображается текст вопроса.
    для данного опроса. Вот вид:

     из django. Http импорт Http404
    из джанго.ярлыки импорт рендеринга
    
    из .models import Вопрос
    # ...
    def подробно (запрос, идентификатор_вопроса):
        пытаться:
            question = Question.objects.get (pk = question_id)
        кроме Question.DoesNotExist:
            поднять Http404 ("Вопрос не существует")
        вернуть рендеринг (запрос, 'polls / detail.html', {'вопрос': вопрос})
     

    Новая концепция здесь: представление вызывает исключение Http404
    если вопроса с запрошенным идентификатором не существует.

    Мы обсудим, что вы можете добавить в этот опрос / деталь.html шаблон немного
    позже, но если вы хотите быстро запустить приведенный выше пример, файл
    содержит всего:

    опросы / шаблоны / опросы / detail.html¶

    поможет вам начать работу.

    Ярлык:

    get_object_or_404 ()

    Очень распространена идиома get ()
    и поднимите Http404 , если объект не существует. Джанго
    предоставляет ярлык. Вот деталь () вид , переписанный:

     из django.shortcuts import get_object_or_404, render
    
    из .модели импорт Вопрос
    # ...
    def подробно (запрос, идентификатор_вопроса):
        question = get_object_or_404 (вопрос, pk = question_id)
        вернуть рендеринг (запрос, 'polls / detail.html', {'вопрос': вопрос})
     

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

    Философия

    Почему мы используем вспомогательную функцию get_object_or_404 ()
    вместо того, чтобы автоматически ловить
    ObjectDoesNotExist исключения на более высоком
    уровень, или если API модели поднимет Http404 вместо
    ObjectDoesNotExist ?

    Потому что это связывает слой модели со слоем вида.Один из
    главная цель дизайна Django - поддерживать слабую связь. Некоторый
    управляемая связь представлена ​​в модуле django.shortcuts .

    Также есть функция get_list_or_404 () , которая работает
    так же, как get_object_or_404 () - кроме использования
    фильтр () вместо
    получить () . Это поднимает
    Http404 , если список пуст.

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

    Вернуться к детальному просмотру () для нашего приложения опроса.Учитывая контекст
    переменная вопрос , вот как может выглядеть шаблон polls / detail.html
    нравится:

    опросы / шаблоны / опросы / detail.html¶

     

    {{question.question_text}}

      {% для рассматриваемого выбора.choice_set.all%}
    • {{choice.choice_text}}
    • {% endfor%}

    Система шаблонов использует синтаксис поиска по точкам для доступа к атрибутам переменных. В
    пример {{question.question_text}} , сначала Django выполняет поиск по словарю
    по объекту вопрос .В противном случае он пытается найти атрибут, который
    в этом случае работает. Если поиск атрибута завершился неудачно, он попытался бы
    поиск по списку-индексу.

    Вызов метода происходит в цикле {% for%} :
    question.choice_set.all интерпретируется как код Python
    question.choice_set.all () , который возвращает итерацию из объектов Choice и является
    подходит для использования в теге {% for%} .

    Дополнительные сведения о шаблонах см. В руководстве по шаблонам.

    Удаление жестко заданных URL-адресов в шаблонах¶

    Помните, когда мы писали ссылку на вопрос в polls / index.html
    шаблон, ссылка была частично жестко закодирована следующим образом:

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

     
  • {{question.question_text}}
  • Это работает путем поиска определения URL-адреса, указанного в
    polls.urls модуль. Вы можете точно увидеть, где находится URL-имя элемента "detail"
    определено ниже:

     ...
    # значение 'name', вызываемое тегом шаблона {% url%}
    путь (' /', views.деталь, имя = 'деталь'),
    ...
     

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

     ...
    # добавлено слово "специфика"
    путь ('особенности /  /', views.detail, name = 'detail'),
    ...
     

    Имена URL пространств имён¶

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

    Ответ - добавить пространства имен в ваш URLconf. В опросах / urls.py
    файл, продолжайте и добавьте app_name , чтобы установить пространство имен приложения:

     из django.путь импорта URL
    
    из . импорт просмотров
    
    app_name = 'опросы'
    urlpatterns = [
        путь ('', views.index, name = 'index'),
        путь (' /', views.detail, name = 'detail'),
        путь (' / results /', views.results, name = 'results'),
        путь (' / vote /', views.vote, name = 'vote'),
    ]
     

    Теперь измените шаблон polls / index.html с:

    опросы / шаблоны / опросы / index.html¶

     
  • {{question.question_text}}
  • , чтобы указать на подробное представление с пространством имен:

    опросы / шаблоны / опросы / index.html¶

     
  • {{question.question_text}}
  • Когда вы освоитесь с написанием представлений, прочитайте часть 4 этого руководства, чтобы узнать основы обработки форм и общих
    взгляды.

    url - Тег шаблона Django

    Первый аргумент - это имя шаблона URL.Это может быть литерал в кавычках или любая другая контекстная переменная. Дополнительные аргументы являются необязательными и должны быть значениями, разделенными пробелами, которые будут использоваться в качестве аргументов в URL.

    url - шаблон Django Теги Объяснение

    Иллюстрация использования тега url в шаблонах Django на примере. Рассмотрим проект geeksforgeeks , в котором есть приложение geeks .

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

    Теперь создайте два представления, через которые мы будем обращаться к шаблону,
    В geeks / views.py ,

    из django.shortcuts import render

    def geeks_view (запрос):

    возврат render (запрос, "geeks.html" )

    def nav_view (запрос):

    возврат рендер (запрос, "nav.html " )

    Создайте путь URL-адреса для сопоставления с этим представлением. URL-адреса должны иметь имя, которое затем может использоваться в шаблонах и с тегом URL-адреса . В geeks / urls.py ,

    из django.urls import path

    из .views import geeks_view, nav_view

    900l = [

    путь ( '1 /' , geeks_view, name = "template1" ),

    путь ( '2 / ' , nav_view, name = "template2" ),

    ]

    Теперь создадим съел два шаблона, чтобы продемонстрировать , теперь тег .Создайте шаблон в geeks.html ,

    < html >

    < h2 > Шаблон 1 h2 >

    a href = "{% url 'template2'%}" > Перейти к шаблону 2 a >

    html >

    Создайте шаблон в гиках.html ,

    < html >

    << h3 > Шаблон 2 h3 >

    < ref = "{% url 'template1'%}" > Перейти к шаблону 1 a >

    html >

    Сейчас посетите http: // 127.0.0.1: 8000/1,

    Щелкните ссылку, и она будет перенаправлена ​​на другой URL.

    Расширенное использование

    предположим, что у вас есть представление app_views.client , URLconf которого принимает идентификатор клиента (здесь client () - это метод внутри файла представлений app_views.py). Строка URLconf может выглядеть так:

     path ('client /  /', app_views.client, name = 'app-views-client') 

    Если URLconf этого приложения включен в URLconf проекта в разделе путь, например:

     путь ('клиенты /', include ('имя_проекта.app_name.urls ')) 

    … затем в шаблоне вы можете создать ссылку на это представление следующим образом:

     {% url' app-views-client 'client.id%} 

    Тег шаблона будет выводить строка / clients / client / 123 /.

    Используется {% url ??? %} в шаблонах django

    Я много смотрел в Google в поисках ответов о том, как использовать тег url в шаблонах, только чтобы найти много ответов, в которых говорилось: «Просто вставьте его в свой шаблон и укажите на представление, для которого требуется URL-адрес».static / (? P . *) $ ',' django.views.static.serve ', {' document_root ': settings.MEDIA_ROOT}),
    )

    Мой "views.py" в моем каталоге "login" выглядит так:

      из django.shortcuts import render_to_response, перенаправить
    из django.template импорт RequestContext
    из django.contrib import auth
    
    def login_view (запрос):
        если request.method == 'POST':
            uname = request.POST.get ('имя пользователя', '')
            psword = request.POST.get ('пароль', '')
            user = auth.аутентифицировать (имя пользователя = uname, пароль = psword)
            # если пользователь авторизован и активен
            если user не None и user.is_active:
                auth.login (запрос, пользователь)
                return render_to_response ('main / main.html', {}, context_instance = RequestContext (запрос))
                #return redirect (main_view)
            еще:
                return render_to_response ('loginpage.html', {'box_width': '402', 'login_failed': '1',}, context_instance = RequestContext (запрос))
        еще:
            return render_to_response ('loginpage.html ', {' box_width ':' 400 ',}, context_instance = RequestContext (запрос))
    
    def logout_view (запрос):
        auth.logout (запрос)
        return render_to_response ('loginpage.html', {'box_width': '402', 'logged_out': '1',}, context_instance = RequestContext (запрос))
      

    и, наконец, main.html, на который указывает login_view:

      
    
    контрольная работа!  выйти  
    
      

    Так почему я каждый раз получаю «NoReverseMatch»?

    * (немного другое примечание, мне пришлось использовать context_instance = RequestContext (request) в конце всех моих запросов на рендеринг в ответ, потому что в противном случае он не распознал бы {{MEDIA_URL}} в моих шаблонах, и я не мог ссылаться на любые файлы css или js.Я не уверен, почему это так. Мне не кажется правильным) *

    python - тег URL-адреса шаблона Django 1.8 TypeError

    Я пытаюсь научиться использовать тег URL шаблона Django, чтобы сделать мой код более универсальным, но у меня возникает какое-то исключение.

      Тип исключения: TypeError
    Значение исключения: аргумент функции reversed () должен быть последовательностью
      

    Вот мой глобальный urls.py

      из django.conf.urls import include, url
    из джанго.(? P  [0-9] +) / vote / $ ', views.vote, name =' vote ')
    }
      

    А вот один шаблон, в котором я пытаюсь использовать эту функцию.

      {% if latest_question_list%}
      
    {% еще %}
      

    Нет доступных опросов.

    {% endif%}

    Отслеживание:

      Файл "/ home / polydo_s / Projects / Modeling / venv / lib / python3.4 / site-packages / django / core / handlers / base.py "в get_response
      132. response = wrapped_callback (запрос, * callback_args, ** callback_kwargs)
    Файл "/home/polydo_s/Projects/Modeling/app/polls/views.py" в индексе
      11. возврат рендера (запрос, 'polls / index.html', контекст)
    Файл "/home/polydo_s/Projects/Modeling/venv/lib/python3.4/site-packages/django/shortcuts.py" в рендере
      67. имя_шаблона, контекст, запрос = запрос, using = using)
    Файл "/ home / polydo_s / Projects / Modeling / venv / lib / python3.4 / site-packages / django / template / loader.py "в render_to_string
      99. return template.render (контекст, запрос)
    Файл "/home/polydo_s/Projects/Modeling/venv/lib/python3.4/site-packages/django/template/backends/django.py" в рендере
      74. вернуть self.template.render (контекст)
    Файл "/home/polydo_s/Projects/Modeling/venv/lib/python3.4/site-packages/django/template/base.py" в рендере
      209. return self._render (контекст)
    Файл "/ home / polydo_s / Projects / Modeling / venv / lib / python3.4 / site-packages / django / template / base.py "в _render
      201. return self.nodelist.render (контекст)
    Файл "/home/polydo_s/Projects/Modeling/venv/lib/python3.4/site-packages/django/template/base.py" в рендере
      903. bit = self.render_node (узел, контекст)
    Файл "/home/polydo_s/Projects/Modeling/venv/lib/python3.4/site-packages/django/template/debug.py" в render_node
      79. return node.render (контекст)
    Файл "/home/polydo_s/Projects/Modeling/venv/lib/python3.4/site-packages/django/template/defaulttags.py "в рендере
      329. вернуть nodelist.render (контекст)
    Файл "/home/polydo_s/Projects/Modeling/venv/lib/python3.4/site-packages/django/template/base.py" в рендере
      903. bit = self.render_node (узел, контекст)
    Файл "/home/polydo_s/Projects/Modeling/venv/lib/python3.4/site-packages/django/template/debug.py" в render_node
      79. return node.render (контекст)
    Файл "/home/polydo_s/Projects/Modeling/venv/lib/python3.4/site-packages/django/template/defaulttags.py" в рендере
      217.nodelist.append (node.render (контекст))
    Файл "/home/polydo_s/Projects/Modeling/venv/lib/python3.4/site-packages/django/template/defaulttags.py" в рендере
      493. url = reverse (view_name, args = args, kwargs = kwargs, current_app = current_app)
    Файл "/home/polydo_s/Projects/Modeling/venv/lib/python3.4/site-packages/django/core/urlresolvers.py" в обратном порядке
      579. return force_text (iri_to_uri (resolver._reverse_with_prefix (view, prefix, * args, ** kwargs))))
    Файл "/ home / polydo_s / Projects / Modeling / venv / lib / python3.4 / site-packages / django / core / urlresolvers.py "в _reverse_with_prefix
      433. Я._populate ()
    Файл "/home/polydo_s/Projects/Modeling/venv/lib/python3.4/site-packages/django/core/urlresolvers.py" в _populate
      308. для имени в pattern.reverse_dict:
    Файл "/home/polydo_s/Projects/Modeling/venv/lib/python3.4/site-packages/django/core/urlresolvers.py" в reverse_dict
      338. self._populate ()
    Файл "/home/polydo_s/Projects/Modeling/venv/lib/python3.4/site-packages/django/core/urlresolvers.py "в _populate
      285. для обратного шаблона (self.url_patterns):
      

    Я искал это в течение нескольких часов и, кажется, следую всем рекомендациям, чтобы это работало, но, конечно, что-то должно быть не так.

    Шаблон URL-адреса

    Django - AskPython

    В этой статье мы узнаем о критическом теге языка шаблонов Django - теге шаблона URL-адреса Django и узнаем, как его использовать.

    Что такое тег шаблона URL?

    Тег шаблона URL-адреса - это типичный тип тега в структуре Django Template Language .Этот тег специально используется для добавления URL-адресов просмотра в файлы шаблонов.

    В файле шаблона HTML теги URL используются с атрибутом Anchor, HTML, который обрабатывает все URL-адреса в HTML

    Зачем нам нужен тег URL Django?

    Когда мы можем добавить URL-адрес View напрямую, какова цель тега шаблона URL-адреса Django?

    Давайте посмотрим на простой HTML-тег href.

     Информация о book1 
     

    Мы знаем, что он принимает статический URL-адрес и позволяет нам переходить по ссылке.

    Представления получают данных от клиента через URL-адрес. Например, в представлении ниже:

    def View (запрос, book_id):
        #Код
        вернуть рендеринг (запрос, 'Template.html', {'article_id': article_id})
     

    В этом случае путь URL будет:

    путь ('book / ', View, name = 'Books_View')
     

    Здесь book_id может изменяться от книги к книге.

    Следовательно, прямое добавление этого URL-адреса, конечная точка которого зависит от book_id, нецелесообразно.И вот здесь появляется тег URL.

    Практическое занятие с тегом URL-адреса шаблона

    Чтобы использовать тег шаблона, нам потребуются правильные представления !! Итак, давайте сначала создадим несколько простых представлений для работы.

    Тег шаблона URL

    Синтаксис тега шаблона URL довольно прост:

    {% url 'View_Name' переменная1 переменная2 ...%}
     

    Здесь имя просмотра - это имя, присвоенное ему в URL-адресах .py файл. Variable1, Variable 2 и т. Д. Являются входными аргументами для конкретного представления.

    1. Создайте представления

    Добавьте следующий код в Views.py

    def View1 (запрос):
        вернуть рендер (запрос, 'page1.html')
     

    Теперь мы также создадим простое представление, также принимающее данные, вводимые пользователем. Также добавьте в файл следующие «» .

    def View2 (запрос, идентификатор):
        вернуть рендеринг (запрос, 'page2.html', {'id': id})
     

    Пути URL для обоих представлений будут:

        путь ('page /', View1, name = 'webpage1'),
        путь ('page / ', View2, name = 'webpage2'),
     

    Подробнее о настройке представлений читайте в статье «Представления Django».

    2. Создайте файл шаблона

    Теперь создайте файл шаблона «page1.html» и добавьте код в файл.

    Веб-страница 1

    Нажмите здесь, чтобы открыть книгу 2

    Давайте также создадим «page2.html» .

    Веб-страница2

    Вернуться

    Реализация тега URL Django

    Довольно кода, давайте теперь запустим программу.Следовательно, перейдите к терминалу и запустите свой сервер.

    сервер запуска python manage.py
     

    Перейдите по URL-адресу «/ page»:

    Веб-страница 1

    Щелкните ссылку и проверьте

    Веб-страница 2

    Вот и все, посмотрите, насколько просто использовать тег шаблона URL !!

    Заключение

    Вот и все, ребята !! Это все о теге шаблона URL. Прочтите статью Django Templates , а также статью DTL для получения дополнительной информации о шаблонах.

    Увидимся в следующей статье !! А пока продолжайте кодировать !!

    URL-адреса, представления и шаблоны Django - документация по Python 401 2.1

    В этой лекции мы исследуем базовую схему цикла запроса / ответа Django.

    Введение в Django Views

    Просмотры очень похожи в Django на то, как они находятся в Pyramid

    .

    • Это товарные позиции
    • Они принимают запрос как первый аргумент
    • Вместо того, чтобы возвращать словарь для какого-либо другого средства визуализации, например Pyramid, Django возвращает объект ответа, который включает отрисованный шаблон или текст.

    Еще одно отличие состоит в том, что в Pyramid, когда вы получаете запрос и вызывается представление, если есть биты URL-адреса, которые совпадают с маршрутом, который привел к этому конкретному представлению, где они отображаются?
    Они появляются в аспекте запроса под названием matchdict .
    Он содержит части URL-адреса, которые были сопоставлены маршрутом на пути к сопоставлению с представлением.

    В Django это происходит по-другому.
    Элементы из пути запроса, которые совпадают с шаблоном, в конечном итоге передаются вам в качестве аргументов для вашего вызываемого представления.

    Что значит быть вызываемым в Python? Значит, это объект, который можно вызвать. Если это класс, у него есть метод __call __ () , если это функция, он автоматически получает метод __call __ () . Все, что имеет скобки () в конце, вызывается в Python.

    Django в основном перешел на то, что называется «представлениями на основе классов».
    Вы определяете класс, и этот класс имеет набор методов, и эти методы взаимодействуют, и в конце они возвращают объект ответа.На самом деле вы никогда не определяете метод call, потому что, когда вы создаете представление на основе класса, вы наследуете одну из встроенных базовых версий Django.
    В корне дерева наследования находится реализация метода __call __ () , который работает практически в любой ситуации.

    Мы поговорим здесь несколько минут, но рассмотрим представления функций, это старый способ работы Django.
    Причина в том, что мы хотим разобрать, как представление работает на самом общем уровне.Давайте на мгновение подумаем, как мы подключим представление в Django.

    Что является отправной точкой для перехода от входящего запроса к фрагменту кода, который ответит на этот запрос?
    С чего мы начали в Пирамиде?
    Мы начали с маршрута.
    Маршрут - это путь, по которому запрос ведет к представлению.
    Что мы называем маршрутами в Django?
    URL-адреса.
    Мы видели в нашем проекте Django в каталоге нашего сайта наш файл urls.py .
    Мы устанавливаем статический URL-адрес, указывающий на наш каталог мультимедиа.

    Django создает такие вещи, которые называются urlpatterns .В основном это просто списки вызовов функции url .
    url () происходит от django.conf.urls и отвечает за соединение двух вещей:

    1. Шаблон, который используется для сопоставления входящего запроса.
    2. Вид, на который будет указывать.

    Нам не нужно указывать только на просмотры, мы также можем указывать на другие подтверждения URL.
    Но давайте начнем с того, что укажем на вид.
    Давайте начнем с нового URL и добавим регулярное выражение.»И« $ »в начале и в конце строки маршрута означают это. (Дополнительную информацию см. В документации по регулярным выражениям.)

  • Второй аргумент - это вызываемый элемент, который выполняется при сопоставлении маршрута. lending_library.views.home_view будет искать в нашем текущем каталоге пакет с именем views и искать там функцию home_view () .
  • Третий аргумент для url () - это необязательный аргумент с именем name , который предоставляет дескриптор, который мы можем использовать для вызова обратного в Django и восстановления этих URL-адресов.Помните, что в Pyramid у нас в объекте запроса была функция с именем route_url () .
  • Требуется имя маршрута и, возможно, некоторые аргументы, которые совпадают с заполнителями в этом маршруте.
  • Он вернул обработанный URL, который будет идти по этому маршруту.
  • Django имеет ту же систему, и она называется reverse , и она позволяет вам создавать URL-адреса с учетом имени представления и некоторых аргументов, которые будут соответствовать заполнителям в этом URL-адресе.Прямо сейчас у нас нет никаких аргументов, поэтому мы могли бы просто сказать reverse.homepage и получить обратно URL-адрес для просмотра домашней страницы.

Мы уже говорили, что у нас есть файл с именем views и что он содержит функцию home_view () .
Это существует на данный момент?
Нет.
У нас также должна быть ошибка линтера, отображаемая на наших представлениях часть lending_library.views.home_view .
Это говорит нам о том, что у нас нет представления , импортированных как символ в наше текущее пространство имен.У Django есть два способа справиться с этим.

  • Мы можем импортировать просмотров
  • из lending_library импортировать представления , чтобы специально получить представления из определенного приложения
  • или мы можем преобразовать 'lending_library.views.home_view' как строку. Когда мы это сделаем, Django попытается выполнить оператор импорта. Пока просмотров действительно импортируются, это будет работать.
    • Это хороший способ избежать проблем циклического импорта. urls.py может быть опасным местом, потому что вы будете импортировать сюда много файлов просмотра. Эти представления будут импортировать модели. Эти модели могут импортировать что-то еще, что указывает на urls.py . Легко случайно создать проблемы с циклическим импортом. Если вы передадите импорт в виде строк, этой проблемы можно избежать.

lending_library / lending_library / urls. admin /', включить (admin.$ ', home_view, name =' домашняя страница ')
]
...

Что мы видим в настоящий момент?

 def home_view (запрос):
    "" "Вызываемый вид на главную, для домашней страницы." ""
    return "Hello World!"
 

Простая строка.
Это не то, что ищет Django.
Помните, что представления Django должны возвращать что-то, что можно использовать в качестве ответа.
Ему нужны заголовки и все остальное, что делает правильный HTTP-ответ.
Итак, Django предоставляет нам объект HttpResponse .Давайте добавим это к нашему представлению, чтобы наша функция могла его использовать:

lending_library / lending_library / views.py

 из django.http import HttpResponse


def home_view (запрос):
    "" "Вызываемый вид на главную, для домашней страницы." ""
    return HttpResponse ("Hello World!")
 

Теперь, когда поступит запрос, мы создадим ответ с таким «Hello World!» строка в нем.
Мы должны увидеть, как наше приложение возвращает это в нашем браузере.

Давайте запустим наш тестовый сервер и перейдем к http: // localhost: 8000/:

Это основная форма представления Django:

  • Поступает запрос
  • Вы что-то делаете с ним
  • И затем вы возвращаете то, что работает как ответ.

Вы можете создать ответ вручную, как наша текущая функция home_view () . Вы также можете отображать шаблоны.

Шаблонизатор Django

Загрузка шаблона - это то, чем мы хотим заняться.
Мы можем создать шаблон или загрузить его откуда-то еще.
Давайте посмотрим, где это можно сделать, проверив Django в оболочке:

$ оболочка python manage.py

 В [1]: из шаблона импорта django
В [2]: dir (шаблон)
Из [2]:
['Контекст',
 'ContextPopException',
...
 'двигатели',
 'погрузчик',
]
 

Хотим дополнительно осмотреть погрузчик объект

 В [3]: из загрузчика импорта django.template

В [4]: ​​dir (загрузчик)
Из [4]:
['DeprecationInstanceCheck',
 'LoaderOrigin',
 'Источник',
 'RemovedInDjango20Warning',
...
 'двигатели',
 'get_template',
]
 

Из множества классов и функций, принадлежащих объекту загрузчика , мы ищем get_template .
Давайте воспользуемся этим в нашем views.py :

lending_library / lending_library / views.py

 из django.http import HttpResponse
из загрузчика импорта django.template


def home_view (запрос):
    "" "Вызываемый вид на главную, для домашней страницы." ""
    template = loader.get_template ('lending_library / home.html')
    return HttpResponse ("Hello World!")
 

Это подводит нас к идее загрузчиков шаблонов и того, где Django ищет шаблоны.
По умолчанию Django поставляется с системой, которая позволяет ему искать внутри любого установленного приложения каталог, который называется шаблонами .И он начнет искать шаблоны в этом каталоге.
Если мы хотим иметь шаблоны в корне конфигурации lending_library , нам нужно добавить lending_library в список INSTALLED_APPS .

 INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'patron_profile',
    'lending_library' # <- добавьте это!
]
 

Так, например:

lending_library / lending_library / templates / lending_library / home.HTML

 


   Домашняя страница> 


  

Привет, мир!

Теперь у нас есть html-файл, который находится в каталоге templates внутри одного из наших приложений.
Так работает Django по умолчанию.
Если мы запустим наш сервер, мы обнаружим, что при поступлении запроса наша функция home_view получает его и пытается загрузить шаблон.

Теперь мы изменим наш файл views.py для обработки шаблонов и поместим в него точку останова, чтобы мы могли проверить некоторые вещи:

lending_library / lending_library / views.py

 из django.http import HttpResponse
из загрузчика импорта django.template


def home_view (запрос):
    "" "Вызываемый вид на главную, для домашней страницы." ""
    import pdb; pdb.set_trace ()
    template = loader.get_template ('lending_library / home.html')
    response_body = шаблон.оказывать()
    вернуть HttpResponse (response_body)
 

Когда мы снова попытаемся перейти на нашу домашнюю страницу, мы зайдем в наш отладчик:

 -> template = loader.get_template ('lending_library / home.html')
(Pdb) сущ.
> ... / lending_library / lending_library / views.py (8) home_view ()
-> response_body = template.render ()
(PDB) шаблон
<объект django.template.backends.django.Template по адресу 0x11252ed50>
 

Итак, у нас есть объект-шаблон. Посмотрим:

 (Pdb) dir (шаблон)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__ __init_subclass__ ',' __le__ ',' __lt__ ',' __module__ ',' __ne__ ',' __new__ ',' __reduce__ ',' __reduce_ex__ ',' __repr__ ',' __setattr__ ',' __sizeof__sub__, '__sizeof__s__ , '__weakref__', 'backend', 'origin', 'render', 'template']
 

Вы можете видеть, что render - это один из методов шаблона .Что произойдет дальше?

 (Pdb) л
  3
  4
  5 def home_view (запрос):
  6 "" "Вызываемый вид на главную, для домашней страницы." ""
  7 импорт pdb; pdb.set_trace ()
  8 шаблон = loader.get_template ('lending_library / home.html')
  9 -> response_body = template.render ()
  10 вернуть HttpResponse (response_body)
[EOF]
(Pdb) сущ.
> ... / lending_library / lending_library / views.py (10) home_view ()
-> вернуть HttpResponse (response_body)
(Pdb) response_body
u ' \ n  \ n  \ n  Домашняя страница>  \ n  \ n  \ n 

Hello World!

\ n \ n \ n ' (PDB)

Итак, мы получили строку, которая была преобразована в HTML.

Метод render () очень похож на рендеринг в Python.

response_body = template.render ({'foo': 'bar'})

 
  

Здравствуйте, {{foo}}!

Язык шаблонов Django выглядит так же, как Jinja2, и на самом деле в более поздних версиях Django (> = 1.8) вы можете указать, какой шаблонизатор вы хотите использовать, и это может быть Jinja2.

При использовании Django вам рекомендуется попробовать использовать язык шаблонов Django, потому что он старается как можно больше отводить обработку значений от шаблонов, а вместо этого выполняет обработку на python.

Итак, вот такой узор:

  1. где берем заявку
  2. загружаем шаблон
  3. мы визуализируем этот шаблон и передаем ему какой-то контекст
  4. мы используем визуализированное тело этого и возвращаем его в результате нашего вызова

Это обычная вещь в Django.
На корневом уровне это всегда шаблон.

Мы немного поговорим о том, как этот шаблон может измениться.
Давайте добавим еще один URL к нашим urlpatterns и новый test_view .(\ d +) / $ ', test_view, name =' testme '),
]
...

lending_library / lending_library / views.py

 ...
def test_view (запрос, foo):
    "" "Тестовое представление, вызываемое для тестовых шаблонов URL." ""
    template = loader.get_template ('lending_library / home.html')
    response_body = template.render ({'foo': foo})
    вернуть HttpResponse (response_body)
 

Важно отметить, что при изменении URL-адресов рекомендуется перезапустить сервер, поскольку они часто кэшируются.(\ d +) / (\ w +) / $ ', test_view, name =' testme '),

И изменим наши представления так, чтобы test_view принимал foo и bar :

lending_library / lending_library / views.py

 ...
def test_view (запрос, foo, bar):
    "" "Тестовое представление, вызываемое для тестовых шаблонов URL." ""
    template = loader.get_template ('lending_library / home.html')
    response_body = template.render ({'foo': foo}, {'bar': bar})
    вернуть HttpResponse (response_body)
 

И примите нашу новую переменную bar в наш шаблон:

lending_library / lending_library / templates / lending_library / home.HTML

 


   Домашняя страница 


  

Здравствуйте, {{foo}}!

Как дела, {{bar}}?

Теперь наша страница отображается так:

Если мы решим передумать и использовать аргументы ключевого слова вместо позиционных аргументов, мы сможем это сделать:

lending_library / lending_library / urls.(? P \ d +) / (? P \ w +) / $ ', test_view, name =' testme '),
]
...

lending_library / lending_library / views.py

 ...
def test_view (запрос, число = 0, имя = 'воздушные шары'):
    "" "Тестовое представление, вызываемое для тестовых шаблонов URL." ""
    template = loader.get_template ('lending_library / home.html')
    response_body = template.render ({'foo': num, 'bar': name})
    вернуть HttpResponse (response_body)
 

Итак, теперь мы можем изменить порядок, в котором используются аргументы, потому что они являются ключевыми словами:

def test_view (запрос, имя = 'воздушные шары', число = 0):

response_body = шаблон.render ({'foo': name, 'bar': num})

Это взаимосвязь между URL-адресами и шаблонами, которые вы настроили для URL-адресов, и сигнатурами вызовов, которые вы пишете для представлений.
Заполнители будут переданы в качестве аргументов вашим представлениям.
Это сильно отличается от того, как работают пирамиды.
Эти аргументы могут быть ключевыми аргументами, если созданные вами заполнители помечены синтаксисом (? P <...>) .
Это стандартный синтаксис регулярного выражения Python.

Вопрос. Итак, поскольку мы передаем значения по умолчанию в аргументы вашего ключевого слова, если мы не передадим их в URL-адрес, будут ли использоваться значения по умолчанию?

Давай попробуем.(? P \ d +) / (? P \ w *) / $ ', test_view, name =' testme '),

Значит, он не использовал значение по умолчанию.
Тот факт, что мы предоставили их, на наш взгляд, немного отвлекает.
Если URL-адрес будет совпадать, будет какое-то значение, и оно будет передано.
Но именно так вы делаете необязательные аргументы ключевого слова - предоставляя им значение по умолчанию.

Можно создать шаблоны URL-адресов Django, в которых есть полностью необязательные фрагменты, которые могут присутствовать или отсутствовать.Сделать это не так-то просто.
Требуется несколько сложных шаблонов регулярных выражений.
Возможно, это тоже не лучший способ делать что-то.
Иногда лучше сделать так, чтобы несколько шаблонов URL указывали на одно и то же представление.
Здесь мы можем создать второй шаблон, который содержит только совпадающую часть , и тогда наше необязательное ключевое слово по умолчанию фактически передаст его значение.

Вы должны указать здесь значение по умолчанию, чтобы оно было параметром ключевого слова.
Однако, если вы не создадите специальный сложный шаблон соответствия или второй URL-адрес, в котором не используется ключевое слово и который указывает на то же представление, он не будет использовать параметр по умолчанию.

Ярлыки Django

Идея загрузки шаблона, рендеринга шаблона и возврата ответа настолько распространена, что Django создал несколько ярлыков, которые означают одно и то же.
Ярлыки называются render и render_to_response .

render принимает в качестве обязательных аргументов запрос и имя_шаблона .
Также есть несколько необязательных аргументов.

Давайте немного рассмотрим это.Нам нужно переписать наш views.py :

lending_library / lending_library / views.py

 # from django.http import HttpResponse <- заменить эту строку
# из загрузчика импорта django.template <- и эта строка
from django.shortcuts import render # <- с этой строкой


def home_view (запрос):
    "" "Вызываемый вид на главную, для домашней страницы." ""
    context = {'foo': 'name', 'bar': 'num'}
    возврат рендеринга (запрос, 'lending_library / home.html', context = context)
...
 

Итак, наш ярлык render принимает в качестве аргумента запрос , шаблон («home.html») и наш жестко заданный контекст.

Давайте вернемся на нашу главную страницу и посмотрим, как она выглядит сейчас:

http: // localhost: 8000/

Мы можем сделать то же самое с нашим test_view :

lending_library / lending_library / views.py

 ...
def test_view (запрос, num = 0, name = 'baloons'):
    "" "Тестовое представление, вызываемое для тестовых шаблонов URL."" "
    context = {'число': число, 'имя': имя}
    возврат рендеринга (запрос, 'lending_library / home.html', context = context)
 

Нам также необходимо изменить наш home.html для работы с нашим test_view :

lending_library / lending_library / templates / lending_library / home.html

 


   Домашняя страница 


  

Здравствуйте, {{name}}!

Как у вас дела {{num}}?

И наш home_view тоже нуждается в корректировке:

lending_library / lending_library / views.py

 def home_view (запрос):
    "" "Вызываемый вид на главную, для домашней страницы." ""
    context = {'имя': 'имя', 'число': 'число'}
    возврат рендеринга (запрос, 'lending_library / home.html', context = context)
 

И мы вернулись к нашим «Привет, блины»

render_to_response

Еще мы можем сделать render_to_response .
Между этими двумя есть разница.
Из документации: «Эта функция предшествовала введению render () и работает аналогично, за исключением того, что она не делает запрос доступным в ответе.Это не рекомендуется и, скорее всего, в будущем будет прекращено ".

На самом деле нет веских причин использовать render_to_response , если только у вас нет особого случая использования.
Вы можете столкнуться с render_to_response в устаревшем коде.
Мы будем использовать render () вместо render_to_response () .

URL-адресов с именем, URL-адрес с аргументами, которые используют имя, обратные ссылки в представлениях и шаблонах, urls.py с атрибутом пространства имен, urls.py с атрибутом вложенного пространства имен, URL-адреса.py с несколькими экземплярами одного и того же приложения и app_name, использовать app_name для определения url, ссылку шаблона, которая использует app_name для определения url

Внутренние ссылки или url проекта
ссылки (например, Home
Страница
), как правило, жестко запрограммированы, независимо от того,
методы для перенаправления пользователей в определенные места или в шаблонах, чтобы
обеспечить адекватную навигацию пользователя. Ссылки с жестким кодированием могут представлять
серьезная проблема обслуживания по мере роста проекта, потому что это приводит к
ссылки, которые сложно обнаружить и исправить.Django предлагает способ
называйте URL-адреса, чтобы на них было легко ссылаться в методах просмотра и
шаблоны.

Самая простая техника, которую можно назвать
URL-адреса Django должны добавить атрибут name в
url определения в urls.py . Листинг 2-16.
показывает, как назвать домашнюю страницу проекта, а также как
ссылка на этот URL из метода представления или шаблона.

Листинг 2-16. URL-адрес Django с именем

.

-------------------------------------------------- --------------------------
# Определение в кофейне / URL.ру
путь ('', TemplateView.as_view (template_name = 'homepage.html'), name = "домашняя страница")

-------------------------------------------------- --------------------------
# Определение в методе просмотра
из django.http import HttpResponsePermanentRedirect
из django.urls импортировать обратный

def метод (запрос):
    ....
    return HttpResponsePermanentRedirect (обратный ('домашняя страница'))

-------------------------------------------------- --------------------------
# Определение в шаблоне
 Вернуться на главную страницу 
 

Определение URL в листинге
2-16 использует путь '' , который
переводится на / или домашнюю страницу, также известную как
корневая директория.Обратите внимание на атрибут name с
домашняя страница значение. Назначив URL-адресу
имя вы можете использовать это значение как ссылку в представлении
методы и шаблоны, что означает любые будущие изменения, внесенные в
URL-адрес, автоматически обновляет все определения URL-адресов в
просмотреть методы и шаблоны.

Далее в листинге 2-16 вы видите
пример метода представления, который перенаправляет управление на
реверс ('домашняя страница') . Django реверс
метод пытается найти определение URL-адреса по заданному имени - в
в этом случае домашняя страница - и заменяет ее соответственно.Аналогично, образец ссылки Вернуться на главную страницу в листинге 2-16 использует
тега Django {% url%} , который пытается найти
URL по первому аргументу - в данном случае домашняя страница
- и замените его соответствующим образом.

То же наименование и подстановка
процесс доступен для более сложных определений URL, таких как
те, у которых есть параметры URL. В листинге 2-17 показан процесс для URL-адреса.
с параметрами.

Листинг 2-17.напитки /

/ ', TemplateView.as_view (template_name =' drinks / index.html '), name = "drink"),

-------------------------------------------------- --------------------------
# Определение в методе просмотра
из django.http import HttpResponsePermanentRedirect
из django.urls импортировать обратный
def метод (запрос):
....
return HttpResponsePermanentRedirect (reverse ('drink', args = (drink.name,)))

-------------------------------------------------- --------------------------
# Определение в шаблоне
Распродажа напитков
Распродажа напитков

Определение URL в листинге
2-17 использует более сложный путь URL-адреса с параметром, который
переводится в URL-адреса в виде / напитки / латте / или
/ напитки / эспрессо / . В этом случае URL-адресу присваивается
имя аргумента имя_питки .

Поскольку URL-адрес использует параметр,
синтаксис для обратного метода и {% url
%}
теги немного отличаются. реверс
требует, чтобы параметры URL были предоставлены в виде кортежа для
args, переменная и тег {% url%}
требует, чтобы аргументы URL были представлены в виде списка значений. Уведомление
в листинге 2-17 параметры могут быть как переменными, так и
жестко запрограммированные значения, если они соответствуют регулярному аргументу url
тип выражения - в данном случае это не цифры.

Для определений URL с дополнительными
чем один аргумент, подход к использованию обратный и
{% url%} идентичен.Для реверс
вы передаете ему кортеж со всеми необходимыми параметрами и
для тега {% url%} вы передаете ему список
значения.

Осторожно Остерегайтесь недопустимых определений URL-адресов с
обратный и {% url%}. Django всегда проверяет при запуске, что все
Действительны определения reverse и {% url%}. Это означает, что если вы
сделать ошибку в обратном методе или определении тега {% url%} -
например, опечатка в имени URL-адреса или типы аргументов не соответствуют
регулярное выражение - приложение не запускается и выдает HTTP
500 внутренняя ошибка.Ошибка для такой ситуации
NoReverseMatch at .... Реверс для 'urlname' с аргументами
'()' и аргументы ключевого слова '{}' не найдены. Х шаблон (ы)
пробовал
. Если вы посмотрите на стек ошибок, вы сможете
определите, где это происходит, и исправьте это. Просто имейте в виду это
является фатальной ошибкой и не ограничивается представлением или страницей, где она
происходит, он остановит все приложение при запуске
вверх.

Иногда использование
имя атрибута самого по себе недостаточно для классификации
URL-адреса.Что произойдет, если у вас есть две или три страницы индекса? Или если ты
есть два URL-адреса, которые квалифицируются как подробные сведения, но один предназначен для магазинов и
другой для напитков?

Грубый подход заключается в использовании
составные имена (например, drink_details, store_details). Тем не менее
использование составных имен в этой форме может затруднить
помните соглашения об именах и небрежную иерархию. Уборщица
подход заключается в использовании структуры приложения Django для управления группами URL-адресов.

Как описано в разделе «Настройка содержимого, понимание URL-адресов, шаблонов и приложений Django в главе 1», проекты Django структурированы вокруг приложений Django, которые служат для разделения определенных аспектов проекта и управления ими.Следовательно, использование концепции приложений Django для управления URL-адресом является естественным подходом для управления возможностью наличия нескольких URL-адресов с одинаковым именем и предотвращения их конфликта друг с другом.

Перечисление 2-18 иллюстрирует серию
определений URL-адресов, которые используют атрибут app_name с , включают .

Листинг 2-18. Django urls.py с атрибутом app_name
-------------------------------------------------- --------------------------
# Содержимое кофейни / URL.ру
из импорта django.urls, путь

urlpatterns = [
    путь ('', TemplateView.as_view (template_name = 'homepage.html'), name = "homepage"),
    путь ('about /', include ('coffeehouse.about.urls')),
    путь ('магазины /', включают ('coffeehouse.stores.urls')),
]

-------------------------------------------------- --------------------------
# Contents coffeehouse / about / urls.py
из пути импорта django.urls
из . импорт просмотров
из . импортировать приложения

# apps.AboutConfig.name = coffeehouse.about
app_name = apps.AboutConfig.название

urlpatterns = [
    путь ('', views.index, name = "index"),
    путь ('контакт /', views.contact, name = "contact"),
]

-------------------------------------------------- --------------------------
# Contents coffeehouse / store / urls.py
из пути импорта django.urls
из . импорт просмотров
из . импортировать приложения

# apps.StoresConfig.name = coffeehouse.stores
app_name = apps.StoresConfig.name

urlpatterns = [
    путь ('', views.index, name = "index"),
    path (' /', views.detail, name = "detail"),
)

-------------------------------------------------- --------------------------
# Определение в просмотрах.py файл
из django.http import HttpResponsePermanentRedirect
из django.urls импортировать обратный

def метод (запрос):
    ....
    return HttpResponsePermanentRedirect (reverse ('coffeehouse.about: index'))

-------------------------------------------------- --------------------------
# Определение в шаблоне
 Вернуться в индекс магазинов 
 

Перечисление 2-18 начинается с набора
включает определений, типичных для основного Django.
URL.py , как и те, что были представлены ранее в листинге 2-13. Далее вы можете увидеть
urls.py файла, на которые есть ссылки в основном
urls.py файл, используйте имя
атрибут, описанный в прошлом примере. Обратите внимание на символы about и
сохраняет urls.py файлов имеют URL с
имя = 'индекс' .

Что еще более важно, обратите внимание на атрибут app_name в каждом дочернем файле urls.py . Значение app_name в каждом файле url указывает на значение name приложения, определенное в приложениях app.py файл конфигурации. Для кофейни / about / urls.py файл app_name = 'coffeehouse.about' , а для кофейни / store / urls.py - app_name = 'coffeehouse.stores' . С помощью значения app_name вы можете различать примерно url name = 'index' и URL-адрес магазина, который также имеет name = 'index' .

Чтобы указать имя URL-адреса с помощью app_name , вы можете использовать синтаксис
<имя_приложения>: <имя> .Как вы можете видеть в направлении
внизу листинга 2-18, чтобы указать индекс в
urls.py вы используете coffeehouse.about: index и to
ссылка на индекс в магазинах urls.py файл, который вы используете
кофейня. Магазины: индекс

Совет Альтернативой использованию атрибута app_name в дочерних файлах urls.py является определение имени приложения как части include в качестве определения вложенного кортежа в основных URL-адресах .py .

Например, путь ('about /', include ('coffeehouse.about.urls')), оператор в листинге 2-18 с именем приложения будет выглядеть как путь ('about /', include (( 'coffeehouse.about.urls', 'coffeehouse.about'))), , это, в свою очередь, позволяет вам ссылаться на URL-адреса в 'coffeehouse.about.urls' с именем приложения 'coffeehouse.about' просто он показан в конце листинга 2-18. Хотя эта альтернатива работает, в таких случаях я рекомендую вам использовать app_name внутри дочерних URL-адресов .py , потому что он чище и всегда будет иметь приоритет перед альтернативой передачи имени приложения в определение include .

Другой пример, когда этот метод кортежа лучше подходит, - это когда основной файл urls.py буквально импортирует список urlpatterns из дочернего файла и, как следствие, теряет видимость значения app_name . В основном файле urls.py вы можете иметь что-то вроде из кофейни.напитки.urls импортируют шаблоны URL-адресов в виде drinks_url_patterns , который импортирует список шаблонов URL-адресов из файла coffeehouse.drinks.urls как drinks_url_patterns - фактически теряя из виду любое значение app_name , определенное в coffeehouse.drinks.urls - а затем в том же основном файле urls.py как часть его значения patterns вы можете объявить путь ('drink /', include ((drinks_url_patterns, 'coffeehouse.drinks'))), , так что все URL-адреса в списке drinks_url_patterns доступны через кофейню .напитки наименование.

В 95% URL-адресов Django вы можете использовать
name , включают параметры и app_name точно так же, как
они были описаны. Однако параметр app_name
приобретает несколько иное значение, когда вы развертываете несколько экземпляров
одно и то же приложение Django в том же проекте.

Поскольку приложения Django
автономные блоки с определениями URL-адресов, возникает крайний случай, когда приложения Django с одним app_name используются несколько раз.Что произойдет, если Django
app использует app_name X, но вы хотите развернуть приложение два или три
раз в одном проекте? Как вы ссылаетесь на URL-адреса в каждом приложении,
учитывая, что все они написаны для использования app_name X? Вот где
термин приложение , экземпляр и пространство имен
атрибут войти в картинку.

Давайте рассмотрим сценарий
который использует несколько экземпляров одного и того же приложения Django для иллюстрации
этот пограничный случай связан с app_name и тем, как используется атрибут пространства имен .Скажем ты
разработать приложение Django под названием баннеры для отображения рекламы. В
приложение баннеров построено таким образом, что оно должно запускаться на разных
URL-адреса
(например, / coffeebanners / , / foodbanners / , / teabanners / )
упростить подбор баннеров. По сути, вам необходимо
запускать несколько экземпляров приложения баннеров в одном проекте, каждый
один на разных URL.

Так в чем проблема множественных
экземпляры приложений и именование URL? Это связано с использованием именованных URL-адресов
которые необходимо динамически изменять в зависимости от текущего экземпляра приложения.Эту проблему легче всего понять на примере, поэтому давайте перейдем к
к примеру в листинге 2-19.

Листинг 2-19. Django urls.py с несколькими экземплярами одного и того же приложения
-------------------------------------------------- --------------------------
# Contents coffee / urls.py
из импорта django.urls, путь

urlpatterns = [
    путь ('', TemplateView.as_view (template_name = 'homepage.html'), name = "homepage"),
    path ('coffeebanners /', include ('coffeehouse.banners.urls'), namespace = "coffee-Banners"),
    path ('foodbanners /', include ('coffeehouse.Banners.urls '), namespace = "food-banner"),
    путь ('teabanners /', include ('coffeehouse.banners.urls'), namespace = "tea-Banners"),
]

-------------------------------------------------- --------------------------
# Contents coffee / Banners / urls.py
из пути импорта django.urls
из . импорт просмотров
из . импортировать приложения

# apps.BannersConfig.name = coffeehouse.banners
app_name = apps.BannersConfig.name

urlpatterns = [
    путь ('', views.index, name = "index"),
]

-------------------------------------------------- --------------------------
# Определение в методе представления с использованием значения пространства имен
из джанго.http импорт HttpResponsePermanentRedirect
из django.urls импортировать обратный

def метод (запрос):
    ....
    return HttpResponsePermanentRedirect (reverse ('food-banner: index'))

-------------------------------------------------- --------------------------
# Определение в шаблоне с использованием значения пространства имен
 Получил экземпляр приложения "Баннеры кофе" & lt / a>
 Получил экземпляр приложения для баннеров еды & lt / a>
 Экземпляр приложения для баннеров на чай & lt / a>

 

В листинге 2-19 вы можете видеть, что мы
иметь три URL-адреса, указывающие на одно и то же
кофейня.Banner.urls файл. Затем обратите внимание, что каждое из объявлений path в дополнение к определению оператора include также имеет значение
пространства имен . Это значение пространства имен - это то, что позволяет вам ссылаться на разные URL-адреса для трех разных экземпляров файла coffeehouse.banners.urls .

Чтобы указать имя URL-адреса с пространством имен , вы можете использовать синтаксис <пространство имен>: <имя> . Обратите внимание в конце листинга 2-19, как можно использовать значение пространства имен как в обратном методе в представлениях, так и в теге {% url%} в шаблонах (например,грамм. утверждение {% url 'tea-Banners: index'%} генерирует ссылку на / teabanners ; оператор reverse ('food-Banners: index') генерирует ссылку на url / foodbanners .

Возможность использовать : для ссылки на URL-адреса позволяет эффективно получать доступ к URL-адресам из нескольких экземпляров одного и того же приложения Django. Однако, полагаясь только на пространство имен , имя и URL-адреса не могут динамически адаптироваться к различным экземплярам приложения, поскольку вам нужно заранее знать (и жестко кодировать), для какого экземпляра приложения вы хотите создать ссылку (например,грамм. / coffeebanners , foodbanners , teabanners ).

Давайте рассмотрим конкретный сценарий, в котором для пространства имен и name значений недостаточно. Предположим, внутри приложения баннеров
вы хотите перенаправить управление на основной URL-адрес индекса приложения (например, из-за
к исключению). Теперь наденьте шляпу дизайнера приложений, как бы вы
решить эту проблему? Как разработчик приложений вы даже не знаете о
пространства имен кофейных баннеров, чайных баннеров или пищевых баннеров, как
это пространства имен развертывания.Как бы вы внутренне интегрировали
перенаправление в приложении, которое адаптируется к нескольким экземплярам приложения
развертывается? Здесь снова вступает в игру параметр app_name , представленный в листинге 2-18.

Обратите внимание на urls.py
файл в листинге 2-19 приложения баннеров устанавливает
app_name , чтобы указать на значение name приложения, определенное в файле конфигурации apps.py приложения. Для кофейни / баннеры / URL.py файл app_name = 'coffeehouse.banners' . Поскольку Django использует то же синтаксическое соглашение для поиска имен URL с app_name или namespace совпадений (то есть : или : ), вполне допустимо создание метод обратный , как показано в листинге 2.20.

Листинг 2-20. Перенаправление Django, использующее app_name с несколькими экземплярами приложения для определения URL-адреса
-------------------------------------------------- --------------------------
# Определение в методе просмотра
из джанго.http импорт HttpResponsePermanentRedirect
из django.urls импортировать reversew

def метод (запрос):
    ....
    return HttpResponsePermanentRedirect (reverse ('coffeehouse.banners: index'))
 

Итак, какой URL вы думаете
coffeehose.banners: индекс в листинге 2-20 разрешает? Все зависит от
там, где происходит навигация, она динамична! Если пользователь
перемещение по экземпляру приложения Coffee-Banner (например, url
coffeebanners ) тогда Django решает
кофейный шланг.баннеры: индекс к экземпляру coffee-Banner
index, если пользователь просматривает экземпляр приложения чайных баннеров
(т.е. url teabanners ), тогда Django решает
coffeehose.banners: индекс к экземпляру tea-Banners
index и так далее для любого другого количества экземпляров. В случае, если пользователь
перемещается за пределами экземпляра приложения с баннерами (т.е. нет
app), то Django по умолчанию разрешает
coffeehose.banners: проиндексируйте до последнего определенного экземпляра в
URL.py , которые были бы чайными баннерами.

Таким образом и в зависимости от того, где
экземпляр пути запроса, из которого приходит пользователь (например, если пользователь
по пути с / coffeebanners / или
/ teabanners / ) разрешает обратный метод
coffeehose.banners: динамически индексировать к одному из трех
экземпляры приложения url против жестко заданных пространств имен URL-адресов, как показано
в листинге 2-19.

Подсказка Можно переопределить все вышеперечисленное поведение разрешения, явно указав значение current_app в объекте запроса .Например, изменение запроса с на request.current_app = 'food-banner' перед оператором reverse приводит к разрешению URL-адреса в экземпляр приложения food-Banner . В следующем разделе, посвященном запросам метода просмотра, содержится более подробная информация об объекте запроса .

Теперь предположим, что приложение "Баннеры"
имеет внутренний шаблон со ссылкой на основной
индекс url. Аналогично, как бы вы сгенерировали эту ссылку
в шаблоне, чтобы учесть возможность нескольких
экземпляры приложений? Опираясь на тот же параметр app_name
решает эту проблему для ссылки на шаблон, показанной в листинге
2-21.

Листинг 2-21. Ссылка на шаблон Django, которая использует app_name для
определить URL
-------------------------------------------------- --------------------------
# шаблон баннеры / index.html
 {% url 'coffeehouse.banners: index'%} 
 

Обратите внимание на {% url%}
Тег в листинге 2-21 указывает на coffeehouse.banners: index , где coffeehouse.banners - это app_name , а index - это имя URL.Процесс разрешения проблемы для кофейни . баннеры: индекс
то же, что описано в предыдущем примере метода, в котором используется
обратный метод.

Если пользователь просматривает
экземпляр приложения Coffee-Banner (например, url
coffeebanners ) тогда Django решает
coffeehouse.banners: индекс к экземпляру coffee-Banners
index, если пользователь просматривает экземпляр приложения чайных баннеров
(т.е. url teabanners ), тогда Django решает
кофейня.баннеры: индекс к экземпляру чайных баннеров
index и так далее для любого другого количества экземпляров. В случае, если пользователь
перемещается за пределами экземпляра приложения с баннерами (т.е. нет
app), то Django по умолчанию разрешает
coffeehouse.banners: проиндексируйте до последнего определенного экземпляра в
urls.py , что будет food-banner .

Подсказка Можно переопределить все вышеперечисленное поведение разрешения, явно указав значение current_app в объекте запроса .Например, изменение запроса на request.current_app = 'food-Banners' перед отправкой управления оператору {% url%} позволяет разрешить URL-адрес экземпляру приложения food-Banner . В следующем разделе, посвященном запросам метода просмотра, содержится более подробная информация об объекте запроса .

Наконец, учитывая взаимозаменяемый синтаксис для доступа к URL-адресам с помощью : или : , стоит отметить, что также допустимо иметь вложенный с одним или более значений, за которыми следует url , со значениями, разделенными : .В листинге 2-22 показан пример с такой вложенной структурой имени URL-адреса.

Листинг 2-22. Django urls.py с вложенным атрибутом app_name и namespace
-------------------------------------------------- --------------------------
# Contents coffee / urls.py
из импорта django.urls, путь
из django.views.generic импортировать TemplateView

urlpatterns = [
    путь ('', TemplateView.as_view (template_name = 'homepage.html'), name = "homepage"),
    путь ('магазины /', включают ('кофейня.store.urls '),
]

-------------------------------------------------- --------------------------
# Contents coffeehouse / store / urls.py
из пути импорта django.urls
из . импорт просмотров
из . импортировать приложения

# apps.StoresConfig.name = coffeehouse.stores
app_name = apps.StoresConfig.name

urlpatterns = [
    путь ('', views.index, name = "index"),
    path (' /', views.detail, name = "detail"),
    path (' / about /', include ('coffeehouse.about.urls', namespace = "nested-store-about")),
]

-------------------------------------------------- --------------------------
# Содержание coffeehouse / about / urls.ру
из пути импорта django.urls
из . импорт просмотров
из . импортировать приложения

# apps.AboutConfig.name = coffeehouse.about
app_name = apps.AboutConfig.name

urlpatterns = [
    путь ('', views.index, name = "index"),
    путь ('контакт /', views.contact, name = "contact"),
]

-------------------------------------------------- --------------------------
# Определение в методе просмотра
из django.http import HttpResponsePermanentRedirect
из django.urls импортировать обратный

def метод (запрос):
    ....
    return HttpResponsePermanentRedirect (reverse ('coffeehouse.store: nested-store-about: contact ', args = (store.id,)))

-------------------------------------------------- --------------------------
# Определение в шаблоне
 Узнайте о {{store.name}} 
 

Структура url в листинге 2-22
отличается от предыдущих тем, что создает около URL-адресов для каждого
store (например, / store / 1 / about / ) вместо
общий URL-адрес (например, / about / ).Вверху списка
2-22 мы продолжаем использовать app_name для определения всех URL-адресов в
в магазинах urls.py файла до coffeehouse.stores .

Далее, внутри магазинов
urls.py уведомление о файле есть еще один
включает элемент с namespace = "nested-store-about" от до
квалифицировать все URL-адреса примерно в urls.py . И наконец
внутри файла около urls.py есть URL-адреса,
просто используйте атрибут name .В последней части
листинг 2-22, вы можете увидеть, как вложенные значения для : : объявлены как coffeehouse.stores: nested-store-about: contact и используются с
обратный метод и тег {% url%} .

.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *