Как выполнять обратный поиск по URL-адресу в приложении для повторного использования в Django
Учтите, что я включаю многоразовое приложение с именами:
urlpatterns = patterns('',
# ella urls
url('^ella/', include('ella.core.urls', namespace="ella")),
)
Теперь приложения Ella имеют такие же URL:
urlpatterns = patterns( '',
url( r'^(?P<category>[a-z0-9-/]+)/$', category_detail, name="category_detail" ),
# object detail
url( r'^(?P<category>[a-z0-9-/]+)/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<content_type>[a-z0-9-]+)/(?P<slug>[a-z0-9-]+)/$',
object_detail, name="object_detail" )
)
Теперь вызов {% url ella:category_detail category="cat" %}
работает нормально. Однако, когда объект пытается создать ссылку на него, он вызывает
from django.core.urlresolvers import reverse
url = reverse('object_detail', kwargs={'required' : 'params'})
Это не работает, если не переписано как
from django.core.urlresolvers import reverse
url = reverse('ella:object_detail', kwargs={'required' : 'params'})
Итак, если я правильно понимаю, , включающее многоразовое приложение в пространство имен, разбивает все внутренние обратные() s внутри данного приложения.
Это правда? Что я пропустил? Есть ли способ?
Ответы
Ответ 1
Поскольку у вас есть конфигурация URL-адреса с разнесением по имени, вам нужно указать шаблон пространства имен: view-name, чтобы отменить его правильно (особенно из представления).
Но, если вы хотите этого избежать, вы также можете передать namespace/appname в качестве параметра current_app.
Существует несколько способов указать current_app, когда вы находитесь в шаблоне. Но если вы видите, вам нужно жестко закодировать, как и вы, или перейти к параметру current_app
url = reverse('object_detail',
kwargs={'foo':'bar'},
current_app=app_name_or_name_space)
: http://docs.djangoproject.com/en/dev/topics/http/urls/#reverse
Ответ 2
Пространства имен URL могут быть указаны двумя способами.
Во-первых, вы можете предоставить пространство имен приложений и экземпляров в качестве аргументов include() при создании шаблонов URL-адресов. Например:
(r '^ help/', include ('apps.help.urls', namespace = 'foo', app_name = 'bar')),
Это право от http://docs.djangoproject.com/en/dev/topics/http/urls/#defining-url-namespaces.
Попробуйте изменить include('ella.core.urls', namespace="ella")
на include('ella.core.urls', namespace="ella", app_name="ella")
. Я не на 100%, это будет работать, но это стоит того.
Ответ 3
По крайней мере, в Django 1.8 вы можете написать примерно следующее:
url = reverse('%s:object_detail' % request.resolver_match.namespace, kwargs={'required' : 'params'})
request.resolver_match.namespace
- это строка, содержащая пространство имен текущего запущенного представления.