Подтвердить что ты не робот

Как передать параметр url в reverse_lazy в Django urls.py

Учтите, что у меня есть 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 (так, что положить вместо <???> в примере выше)?

4b9b3361

Ответ 1

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

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

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

Ответ 2

Я бы не сделал этого непосредственно в 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()),
)

Ответ 3

Redirect View отлично, если вы используете жесткий код, он заменил 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-адреса передается в лямбда-функцию.

Ответ 4

По состоянию на 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'),
    ),
) 

Ответ 5

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

Ответ 6

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

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