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

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)