Что обратное() в Django

Когда я иногда читаю код django, я вижу в некоторых шаблонах reverse(). Я не совсем уверен, что это такое, но он используется вместе с HttpResponseRedirect. Как и когда этот reverse() должен использоваться?

Было бы неплохо, если бы кто-нибудь дал ответ с некоторыми примерами...

Ответ 1

reverse() | Django документация


В вашем urls.py определите это:

url(r'^foo$', some_view, name='url_name'),

В шаблоне вы можете ссылаться на этот URL как:

<!-- django <= 1.4 -->
<a href="{% url url_name %}">link which calls some_view</a>

<!-- django >= 1.5 or with {% load url from future %} in your template -->
<a href="{% url 'url_name' %}">link which calls some_view</a>

Это будет представлено как:

<a href="/foo/">link which calls some_view</a>

Теперь предположим, что вы хотите сделать что-то похожее в вашем views.py - например, вы обрабатываете другой URL (не /foo/) в другом представлении (не some_view) и хотите перенаправить пользователя в /foo/ (часто это так). при успешной подаче формы).

Вы могли бы просто сделать:

return HttpResponseRedirect('/foo/')

Но что, если вы хотите изменить URL в будущем? Вы должны обновить свой urls.py и все ссылки на него в своем коде. Это нарушает " СУХОЙ" ("Не повторяй себя"), всю идею редактирования только одного места, к чему нужно стремиться.

Вместо этого вы можете сказать:

from django.urls import reverse
return HttpResponseRedirect(reverse('url_name'))

Он просматривает все URL-адреса, определенные в вашем проекте, для URL-адреса, определенного с именем url_name и возвращает фактический URL-адрес /foo/.

Это означает, что вы обращаетесь к URL-адресу только по его атрибуту name - если вы хотите изменить сам URL-адрес или представление, к которому он относится, вы можете сделать это, отредактировав только одно место - urls.py

Ответ 2

Это старый вопрос, но кое-что может кому-то помочь.

Из официальных документов:

Django предоставляет инструменты для выполнения реверсирования URL, которые соответствуют разным слоям, где необходимы URL: В шаблонах: Использование тега шаблона URL. В коде Python: использование функции reverse(). В коде более высокого уровня, связанном с обработкой URL-адресов экземпляров модели Django: метод get_absolute_url().

Например. в шаблонах (тег URL)

<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>

Например. в коде Python (с использованием reverse функции)

return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))

Ответ 3

Существует документ для

https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-resolution-of-urls

его можно использовать для создания URL-адреса для данного представления

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

Ответ 4

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

Используйте reverse(), чтобы дать вам URL-адрес страницы, задав либо путь к представлению, либо параметр page_name из вашего URL-адреса. Вы бы использовали его в тех случаях, когда это не имеет смысла делать в шаблоне с помощью {% url 'my-page' %}.

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

return HttpResponseRedirect(reverse('thanks-we-got-your-form-page'))

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

В другой раз, когда я использовал reverse(), был с наложением модели. У меня был ListView на родительской модели, но я хотел получить от любого из этих родительских объектов в DetailView связанного дочернего объекта. Я привязал функцию get__child_url() к родительскому объекту, который идентифицировал существование дочернего элемента и вернул URL-адрес его DetailView с помощью reverse().

Ответ 5

Обратный() используется для закрепления принципа django DRY. Если вы в будущем измените URL-адрес, вы можете ссылаться на этот URL-адрес, используя reverse (urlname).

Ответ 6

Существующие ответы проделали большую работу по объясняя, что этого reverse() функции в Django.

Тем не менее, я надеялся, что мой ответ пролил другой свет на вопрос " почему": зачем использовать reverse() вместо других более простых, возможно, более питонических подходов в привязке к представлению шаблона, и каковы некоторые законные причины популярности этого "перенаправление через шаблон reverse() " в логике маршрутизации Django.

Одним из ключевых преимуществ является обратная конструкция URL, как уже упоминали другие. Точно так же, как вы бы использовали {% url "profile" profile.id %} для генерации URL из файла конфигурации вашего приложения: например, path('<int:profile.id>/profile', views.profile, name="profile").

Но, как отметил OP, использование reverse() также обычно сочетается с использованием HttpResponseRedirect. Но почему?

Я не совсем уверен, что это такое, но он используется вместе с HttpResponseRedirect. Как и когда должен использоваться этот reverse()?

Рассмотрим следующие views.py:

from django.http import HttpResponseRedirect
from django.urls import reverse

def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected = question.choice_set.get(pk=request.POST['choice'])
    except KeyError:
        # handle exception
        pass
    else:
        selected.votes += 1
        selected.save()
        return HttpResponseRedirect(reverse('polls:polls-results',
                                    args=(question.id)
        ))

И наш минимальный urls.py:

from django.urls import path
from . import views

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

В функции vote() код нашего блока else использует reverse вместе с HttpResponseRedirect по следующему шаблону:

HttpResponseRedirect(reverse('polls:polls-results',
                                        args=(question.id)

Это, прежде всего, означает, что нам не нужно жестко кодировать URL (в соответствии с принципом DRY), но, что более важно, reverse() предоставляет элегантный способ создания строк URL, обрабатывая значения, распакованные из аргументов (args=(question.id) обрабатывается URLConfig). Предполагаемый question имеет атрибут id который содержит значение 5, тогда URL, созданный из reverse() будет:

'/polls/5/results/'

В обычном коде связывания представления шаблона мы используем HttpResponse() или render() поскольку они обычно включают меньше абстракции: одна функция представления возвращает один шаблон:

def index(request):
    return render(request, 'polls/index.html') 

Но во многих законных случаях перенаправления мы обычно заботимся о создании URL-адреса из списка параметров. К ним относятся такие случаи, как:

  • Отправка HTML-формы через POST запрос
  • Пост-проверка логина пользователя
  • Сброс пароля через веб-токены JSON

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