Перейти к содержимому

Reverse django что это

  • автор:

django: метод reverse не определён

введите сюда описание изображения

Вылетает вот такая ошибка объявил в модели метод get_absolute_url, для передачи url в шаблон, но метод reverse почему то не работает

def get_absolute_url(self): return reverse("movie_detail", kwargs = ) 

Отслеживать
25.4k 4 4 золотых знака 20 20 серебряных знаков 36 36 бронзовых знаков
задан 23 июл 2020 в 18:27
Denver Toha Denver Toha
2,595 1 1 золотой знак 12 12 серебряных знаков 32 32 бронзовых знака
возможно reversed() ?
23 июл 2020 в 19:58

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Добавьте в скрипт импорт:

from django.urls import reverse 

Отслеживать
ответ дан 23 июл 2020 в 18:30
76.9k 6 6 золотых знаков 56 56 серебряных знаков 123 123 бронзовых знака

from django.urls import reverse def get_absolute_url(self): return reverse("movie_detail", args = (self.url,)) 

Отслеживать
68k 218 218 золотых знаков 79 79 серебряных знаков 221 221 бронзовый знак
ответ дан 22 апр 2022 в 11:20
Дмитрий Волошенко Дмитрий Волошенко

добро пожаловать на Stack Overflow на русском! пожалуйста, постарайтесь оставлять чуть более развёрнутые ответы. дополнить ответ можно, нажав править

22 апр 2022 в 11:21

  • python
  • python-3.x
  • django
    Важное на Мете
Похожие

Подписаться на ленту

Лента вопроса

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.1.3.2953

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Зачем нужен reverse()?

Всем привет, прочитал доку, вроде бы и понятно, но как-то непонятно. Кто может понятно объяснить, зачем нужен reverse()? Зачем он нужен в принципе и зачем он нужен в частности в get_absolute_url?

  • Вопрос задан более трёх лет назад
  • 5470 просмотров

1 комментарий

Простой 1 комментарий

Сергей Горностаев @sergey-gornostaev Куратор тега Django

Метод get_absolute_url должен возвращать url представления для текущего экземпляра модели. Как вы собираетесь возвращать его без reverse ?

Решения вопроса 1

deepblack

reverse позволяет по имени вьюхи получить её url.

from news import views path('archive/', views.archive, name='news-archive')
from django.urls import reverse reverse('news-archive')

get_absolute_url — позволяет получить канонический URL обьекта, при условии что этот метод определён.

# Можно так: def get_absolute_url(self): return "/people/%i/" % self.id # Но лучше так: def get_absolute_url(self): from django.urls import reverse return reverse('people.views.details', args=[str(self.id)])

spoiler

 >">Link >">Link

Маршрутизация — Python: Разработка на фреймворке Django

Важнейшей частью любого веб-фреймворка является механизм, который отвечает за маршрутизацию. Во Flask для построения карты маршрутов использовались специальные декораторы. В Django для этого используется свой небольшой eDSL . Он описывает urlpatterns — набор образцов, с которыми сопоставляются пути из каждого входящего запроса.

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

  • Статические части пути в образце просто проверяются на равенство соответствующим участкам пути в запросе
  • Динамические участки пути позволяют захватывать значения и передавать во view в качестве аргументов

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

В этом уроке подробно разберем статические и динамические маршруты, а также рассмотрим вложенные urlpatterns и обратные маршруты.

Статические маршруты

Мы с вами уже описали один статический маршрут:

urlpatterns = [ path('', views.index), ] 

Здесь path сопоставляет образец » с вьюхой views.index . Образец «пустая строка» соответствует пустому пути — запросам главной страницы сайта. Любой не пустой путь не совпадет с таким образцом. Статические образцы обычно описываются строками вида fruits/apples/golden_one и ожидают запросов строго по этому же пути.

Имя домена не фигурирует в urlpatterns, что позволяет размещать одно и то же приложение на любом домене.

Динамические маршруты

Авторы Django — сторонники использования читаемых URL. Это означает, что маршруты в Django-приложениях выглядят так, что понятно, куда ведет путь. Например, по пути /users/42/pets/101/med_info/ можно догадаться, что запрашивается медицинская информация (med_info) для питомца с идентификатором 101 (pets/101). Он принадлежит пользователю с идентификатором 42 (user/42).

Иногда получается пойти дальше и вместо идентификаторов использовать имена. Например, такое возможно для имен пользователей, которые обычно уникальны в пределах системы. URL при использовании имен может выглядеть так: /users/~bob/books/ .

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

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

Опишем urlpatterns для примера пути, который приведен выше:

## urls.py urlpatterns = [ path('users//pets//med_info/', med_info_view),  ] 
## views.py def med_info_view(request, user_id, pet_id): . 

Здесь означает ту самую динамическую часть пути. int означает, что в этом участке пути ожидается целое число в виде строки. Если сервер получит запрос по пути /users/42/pets/101/med_info/ , маршрутизация закончится вызовом вью med_info_view(request, user_id=42, pet_id=101) .

Кроме int Django предоставляет и другие преобразователи путей — path converters. Более того, можно определять и собственные. А если пути специфические, то всегда можно использовать регулярные выражения, чтобы выделить интересные нам части пути.

Вложенные urlpatterns

Иногда маршрутов становится слишком много и среди них намечаются группы, у которых общая статическая часть. Например, это маршруты ко views одного приложения. В этом случае стоит воспользоваться возможностью включения одних urlpatterns в другие.

Предположим, у нас в проекте есть приложение project.users , в котором все views находятся под общим префиксом /users/. Нам достаточно создать модуль project.users.urls с описанием urlpatterns уже без префикса и подключить модуль в корневой project.urls :

# project.users.urls from django.urls import path from project.users import views urlpatterns = [ path('', views.users_view), path('/pets//med_info/', views.pet_med_info_view),  ] 
# project.urls from django.urls import path, include urlpatterns = [  path('users/', include('project.users.urls')),  ] 

В новом наборе urlpatterns у образцов нет префикса users. А в основном urlpatterns указано, что все пути, которые начинаются с users, нужно сопоставлять с образцами из project.users.urls .

Мы подключили вложенные urlpatterns с помощью функции django.urls.include и указали модуль в виде строки. Можно импортировать модуль и указать вместо цели маршрута сразу его: path(‘users/’, project.users.urls) — эти два варианта эквивалентны. Но неявное подключение вместо импорта решает одну важную задачу: избавляет от потенциальных циклических импортов.

Ранее мы закомментировали в нашем мини-проекте строчку path(‘admin/’, admin.site.urls) . Это тоже включение админки в нашу карту маршрутов по префиксу admin. Подобным образом в приложение часто подключаются сторонние пакеты, у которых собственные маршруты.

Обратные маршруты или reverse

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

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

urlpatterns = [  path( '/pets//med_info/', views.pet_med_info_view, name='pet_med_info', #  ),  ] 

Когда маршрут поименован, можно получить путь вызовом вида reverse(‘pet_med_info’, kwargs=) . Как бы ни менялась маршрутизация в дальнейшем, пока путь содержит те же именованные участки и назван по-старому, эта функция будет давать актуальный для маршрута путь.

Открыть доступ

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

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов

Наши выпускники работают в компаниях:

Перенаправления (redirect). Функция reverse

В Django подобные редиректы достаточно просто выполняются с помощью функции: django.shortcuts.redirect Давайте для примера сделаем перенаправление со страницы архива, если год больше 2023:

def archive(request, year): if year > 2023: return redirect('/') return HttpResponse(f"

Архив по годам

"
)

Здесь в качестве первого параметра указывается страница, на которую происходит перенаправление, в данном случае – это главная страница сайта. Также в файле settings.py вернем прежнее значение параметра DEBUG:

DEBUG = True

Если теперь выполнить запрос: 127.0.0.1:8000/archive/2024/ то мы попадем на главную страницу с кодом перенаправления 302 (см. консоль). Если же нам нужно указать постоянный редирект с кодом 301, то записывается дополнительный параметр:

return redirect('/', permanent=True)

Вообще в качестве первого аргумента функции redirect() можно передавать не только конкретный URL, но и представление. В частности, вместо ‘/’ можно передать ссылку на функцию index следующим образом:

return redirect(index, permanent=True)

В данном случае это будет одно и то же.

Классы HttpResponseRedirect и HttpResponsePermanentRedirect

  • HttpResponseRedirect – для редиректа с кодом 302;
  • HttpResponsePermanentRedirect – для редиректа с кодом 301
def archive(request, year): if year > 2023: return HttpResponseRedirect('/') return HttpResponse(f"

Архив по годам

"
)

На самом деле функция redirect() использует в своей работе эти классы, но, вместе с тем, она несколько более гибкая. Поэтому какой вариант выбирать решает сам программист, исходя из логики построения кода.

Параметр name функции path

Однако указывать в функции redirect, да и вообще где бы то ни было в приложении конкретный URL-адрес (кроме их списка в коллекции urlpatterns) – это порочная практика, или, как еще говорят – хардкодинг. Вместо этого каждому шаблону пути можно присвоить свое уникальное имя и использовать его в рамках всего проекта. Давайте определим имена для наших URL-запросов. Для этого перейдем в файл women/urls.py и в каждой функции path пропишем параметр name с уникальными именами:

urlpatterns = [ path('', views.index, name='home'), path('cats//', views.categories_by_slug, name='cats'), path('cats//', views.categories, name='cats_id'), re_path(r'^archive/(?P[0-9])/', views.archive, name='archive'), ]

Конечно, эти имена вы можете выбрать и другие – это лишь пример. И далее, в функции redirect мы можем выполнить перенаправление на главную страницу, указав имя home:

return redirect('home', permanent=True)

Как видите, это гораздо понятнее и безопаснее использования конкретных URL-адресов. Если в дальнейшем маршрут изменится, то автоматически изменится и адрес перенаправления для home.

Функция reverse()

Если же маршрут помимо имени содержит еще параметры, как например, маршрут ‘cats’ с параметром slug, то для корректного перенаправления необходимо в функции redirect() вторым и последующими аргументами передать требуемые параметры. В нашем случае это можно сделать так:

return redirect('cats', 'music')

В результате, функция redirect() вычислит следующий URL: http://127.0.0.1:8000/cats/music/ и сделает на него перенаправление. Но мы можем разделить операции вычисления URL и непосредственно перенаправление. Для этого в Django имеется функция: django.urls.reverse() которая возвращает строку URL-адреса, вычисленный на основе переданного имени и набора аргументов. Например, для вычисления адреса маршрута cats с параметром ‘music’ функцию reverse() можно вызвать следующим образом:

url_redirect = reverse('cats', args=('music', ))

А, затем, передать этот маршрут в функцию reverse():

return redirect(url_redirect)

или в соответствующий класс:

return HttpResponsePermanentRedirect(url_redirect)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *