Как передать параметр url в reverse_lazy в Django urls.py - PullRequest
21 голосов
/ 27 марта 2012

Учтите, что у меня есть 1 ресурс и 2 URL (скажем, новый и старый), связанные с этим ресурсом.Итак, я хочу настроить перенаправление HTTP для одного из URL.

В myapp/urls.py У меня есть:

urlpatterns = patterns('',
    url(r'^(?P<param>\d+)/resource$', 
                      'myapp.views.resource', 
                       name='resource-view'
    ),
)

В mycoolapp/urls.py Я хочу указать:

from django.views.generic.simple import redirect_to
from django.core.urlresolvers import reverse_lazy

urlpatterns = patterns('',
    url(r'^coolresource/(?P<param>\d+)/$', 
                       redirect_to, 
                       {
                          'url': reverse_lazy('resourse-view', 
                                         kwargs={'param': <???>}, 
                                         current_app='myapp'
                                 ),
                       }
   ),
)

Вопрос в том, как передать <param> в reverse_lazy kwargs (так, что вместо <???> поставить в приведенном выше примере)?

Ответы [ 6 ]

18 голосов
/ 23 января 2013

Я бы не стал делать это напрямую в urls.py, я бы вместо этого использовал основанный на классе RedirectView для вычисления представления для перенаправления на:

from django.views.generic.base import RedirectView
from django.core.urlresolvers import reverse_lazy

class RedirectSomewhere(RedirectView):
    def get_redirect_url(self, param):
        return reverse_lazy('resource-view',
                            kwargs={'param': param},
                            current_app='myapp')

Затем в вашем urls.py вы можете сделать это:

urlpatterns = patterns('',
    url(r'^coolresource/(?P<param>\d+)/$', 
        RedirectSomewhere.as_view()),
)
7 голосов
/ 12 июня 2014

Redirect View отлично подходит, если вы используете жестко запрограммированный URL, он заменил redirect_to, который теперь устарел. Я не думаю, что вы можете использовать его при перенаправлении и реверсе из urls.py. Вот мое решение, x является объектом ответа в этом случае:

from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
urlpatterns = patterns('',
    ....
    url(r'^coolresource/(?P<param>\d+)/$',
                         lambda x, param: HttpResponseRedirect(
                             reverse('myapp.views.resource', args=[param])
                         ),
                         name='resource-view-redirect'),
    ....
)

В этом решении вы все равно можете использовать имя шаблона URL-адреса вместо жесткого URL-адреса. Параметр location_id из URL-адреса передается в лямбда-функцию.

3 голосов
/ 09 июля 2015

Начиная с Django 1.6 вы можете сделать это ( Документация ):

...
from django.views.generic.base import RedirectView

urlpatterns = patterns('',
    url(r'^coolresource/(?P<param>\d+)/$', 
         RedirectView.as_view(pattern_name='resource-view'),
    ),
) 
3 голосов
/ 27 марта 2012

Одним из возможных решений общей проблемы является использование жестко закодированного шаблона URL вместо reverse_lazy ( документация )

url(r'^coolresource/(?P<param>\d+)/$', 
                       redirect_to, 
                       {'url': '/%(param)s/resource'}
),

Но мне это не очень нравится, поскольку мне становится сложнее после внесения возможных изменений в URL.

1 голос
/ 27 марта 2012

Вы не можете знать или получить значение до тех пор, пока не вызывается представление, поэтому рассчитайте url внутри него.

0 голосов
/ 27 марта 2012

Метод сопоставления регулярных выражений в Django для URL-адресов позволяет определять и назначать переменные:

(?P<variable_name>...) определяет variable_name в зависимости от вызываемого uri; поэтому нужно указать: param вместо <???>

...