Як отримати поточну назву URL-адреси за допомогою Django?


91

Я повинен динамічно створювати url відповідно до поточної url. Використання {% url %}тегу - це найпростіший спосіб зробити це, але мені потрібне поточне ім’я url, щоб динамічно генерувати нове.

Як я можу отримати ім'я url, прикріплене до urlconf, що веде до поточного подання?

РЕДАГУВАТИ: Я знаю, що можу вручну обробляти URL-адреси, використовуючи, get_absolute_urlале я волію уникати цього, оскільки це частина лекції, і я хотів би продемонструвати лише один спосіб побудови URL-адрес.

Учні вміють користуватися {% url %}. Вони знають, що стикаються з проблемою, коли їм потрібно створити більш повну URL-адресу на основі поточної. Найпростіший спосіб - використовувати {% url %}знову, з деякими варіаціями. Оскільки ми назвали url, ми повинні знати, як отримати ім'я url, що викликає поточний вигляд.

РЕДАКТУВАТИ 2: інший варіант використання полягає у різному відображенні частин базового шаблону відповідно до базового шаблону. Є й інші способи зробити це (за допомогою CSS та {% block%}, але іноді просто приємно мати можливість видалити тег елемента меню base.html, якщо ім'я перегляду відповідає посиланню.


6
Я продовжував знаходити це питання, шукаючи спосіб вивести поточну абсолютну URL-адресу за допомогою тегу шаблону ... якщо ви теж це шукаєте, це:{{ request.get_full_path }}
Dolph

Відповіді:


134

Я не знаю, як давно ця функція була частиною Django, але, як показує наступна стаття , її можна досягти наступним чином:

   from django.core.urlresolvers import resolve
   current_url = resolve(request.path_info).url_name

Якщо вам це потрібно в кожному шаблоні, написання запиту на шаблон може бути доречним.

Редагувати: ЗАСТОСУВАТИ НОВУ ОНОВЛЕННЯ DJANGO

Після поточного оновлення Django:

Django 1.10 ( посилання )

Імпорт з django.core.urlresolversмодуля застарілий на користь його нового розташування,django.urls

Django 2.0 ( посилання )

django.core.urlresolversМодуль видаляється на користь нового місця, django.urls.

Таким чином, правильний спосіб зробити це так:

from django.urls import resolve
current_url = resolve(request.path_info).url_name

Чому? Наскільки я зрозумів ваше запитання, життєво важливою частиною його було те, як досягти "Оскільки ми назвали url, ми повинні знати, як отримати назву URL-адреси, що викликає поточний погляд" ...
Лукас Бюнгер

1
Насправді, лукас, того дня я був сварливим і відкинув вашу відповідь абсолютно довільно. Перепрошую, бо насправді це правильна відповідь. я збираюся відредагувати його, щоб зробити його більш очевидним.
e-satisfa

8
resolve()не вдається вирішити, якщо ви передаєте йому рядок запиту і просто піднімаєте 404. get_full_path()повертає шлях і рядок запиту. Вам потрібно буде скористатися resolve(request.path_info).
Can Burak Çilingir

Що робити, якщо не currentURL-адреса повинна бути вирішена, а, скажімо, та, на яку користувач збирається перенаправити? Який більш загальний спосіб досягти цього? Відповідь Конлі Оуенса має підказку, але я волів би не винаходити колесо, якщо це колесо вже існує в Джанго під капотом.
Хасан Байг

Здається, це не працює для перекладених URL-адрес із i18n_patterns
guival

109

Починаючи з Django 1.5, це можна отримати з об'єкта запиту

    current_url = request.resolver_match.url_name

https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.resolver_match


Коли я помістив це в контекстний процесор, він працював, але ця дивна помилка була показана в консолі: AttributeError: 'WSGIRequest' object has no attribute 'resolver_match'
fjsj

2
'Resover_match' додається до об'єкта запиту лише після виклику всього проміжного програмного забезпечення запиту. Саме тоді URL-адреси вирішуються. Таким чином, ви можете отримати доступ лише з перегляду проміжного програмного забезпечення далі. (функції process_view проміжного програмного забезпечення). Він не буде доступний у функціях проміжного програмного забезпечення. (функції process_request проміжного програмного забезпечення).
Bharathwaaj

.view_name якщо вам потрібен простір імен

28

Для тих, хто простору імен використовує свої шаблони url, тоді вас може зацікавити назва URL-адреси запиту з простором імен. У цьому випадку view_nameзамість цього зателефонував Django .

request.resolver_match.view_name

# return: <namespace>:<url name>

Дякую, але це майже оману попередньої відповіді @ dariusz-niespodziany, чи не так? stackoverflow.com/a/31931833/1450294
Майкл Шепер

5
Якщо ви не вказали простір імен, ваш urls.py@ dariusz-niespodziany може бути негайно доступним reverse. Але якщо ви використовуєте простір імен, resolver_match.url_nameце не можна безпосередньо використовувати reverse. Таким чином, ви повинні додати простір імен самостійно. Отже, замість того, щоб робити це самостійно, Django вже встановив .view_nameпри ініціалізації.
Yeo

15

Цього можна досягти за допомогою:

    request.resolver_match.url_name

Джанго> 1,8


4

Уточнення питання: "На погляд, як ви отримуєте назву urlpattern, яка вказує на нього, припускаючи, що існує точно один такий urlpattern".

Це може бути бажаним із зазначених причин: зсередини подання ми хочемо СУХИЙ спосіб отримати URL-адресу до того самого представлення (ми не хочемо знати своє власне ім'я url Pattern).

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

Якщо ви дійсно хотіли це зробити, вам доведеться підклас RegexURLResolver і змінити метод вирішення, щоб повернути відповідний шаблон (з якого ви можете отримати ім'я шаблону) замість пар подання та ключового слова / значення. http://code.djangoproject.com/browser/django/trunk/django/core/urlresolvers.py#L142

Потім ви можете створити декоратор або, можливо, більш відповідне проміжне програмне забезпечення, яке використовує цей підклас, щоб отримати ім'я шаблону та зберегти це значення десь у запиті, щоб подання могли його використовувати.

Якщо ви насправді хочете це зробити, і у вас трапляються певні проблеми, повідомте мене про це, і я, можливо, можу допомогти.

Для вашого класу я б просто запропонував їм жорстко закодувати назву шаблону у поданні або шаблоні. Я вважаю, що це прийнятний спосіб зробити це.

Оновлення: Чим більше я думаю про це, тим більше я відмовлятиму від спроб отримати ім'я urlpattern у поданні. Параметри urlpattern досить незалежні від параметрів подання, на яке вони вказують. Якщо ви хочете вказати на певну URL-адресу, вам потрібно знати, як працює шаблон url, а не лише як працює подання. Якщо вам потрібно знати, як працює urlpattern, можливо, вам також доведеться знати назву urlpattern.




1

Це трохи незрозуміло з вашого запитання, але http://docs.djangoproject.com/en/dev/topics/http/urls/ , швидше за все, надасть пояснення того, що ви шукаєте.

Особливо корисно відзначити, як Django обробляє запити:

Коли користувач запитує сторінку з вашого веб-сайту, що працює на Django, це алгоритм, яким система керується, щоб визначити, який код Python виконувати:

  1. Django визначає кореневий модуль URLconf для використання. Зазвичай це значення параметра ROOT_URLCONF, але якщо вхідний об'єкт HttpRequest має атрибут urlconf (заданий обробкою запитів проміжного програмного забезпечення), його значення буде використано замість параметра ROOT_URLCONF.
  2. Django завантажує цей модуль Python і шукає змінні urlpatterns. Це має бути список Python у форматі, поверненому функцією django.conf.urls.defaults.patterns ().
  3. Django проходить по кожному шаблону URL-адреси в порядку і зупиняється на першому, який відповідає запитуваній URL-адресі.
  4. Як тільки один із регулярних виразів збігається, Django імпортує та викликає даний вигляд, який є простою функцією Python. Представлення передається HttpRequest як перший аргумент, а будь-які значення, записані в регулярному виразі, як інші аргументи.

Якщо ви просто після повного шляху, ви можете спробувати:

http://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.get_full_path

Сподіваюся, це допоможе - воно вказує, як використовувати модуль URLconf, і, сподіваємось, допоможе спрямувати вас у правильному напрямку.


Дякую, але я знаю, що :-) Я додав кілька пояснень, щоб уникнути непорозумінь.
e-satisfa
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.