Django возвращает redirect() с параметрами
В моей функции просмотра я хочу вызвать другое представление и передать ему данные:
return redirect('some-view-name', backend, form.cleaned_data)
где backend имеет объект registration.backends, а form.cleaned_data - это форма данных формы (но оба должны быть отправлены как * args или ** kwargs, чтобы предотвратить повышение ошибки Don't mix *args and **kwargs in call to reverse()!
). Из того, что я нашел в документах:
def my_view(request):
...
return redirect('some-view-name', foo='bar')
Похоже, мне нужно предоставить аргумент "some-view-name", но это просто имя функции просмотра или имя URL-адреса? Поэтому я хотел бы сделать это аналогично тому, как это делается в django-registration, где:
to, args, kwargs = backend.post_registration_redirect(request, new_user)
return redirect(to, *args, **kwargs)
def post_registration_redirect(self, request, user):
return ('registration_complete', (), {})
Итак, теперь, могу ли я напрямую вызвать функцию просмотра или мне нужно указать URL-адрес? И что еще важнее, как должен выглядеть мой funciotn (и URL-адрес, если необходимо)? Как бэкэнд, так и cleaned_data просто передаются через это представление для последующего использования. Я пробовал это, но это неправильно:
url(r'^link/$', some-view-name)
def some-view-name(request, *args):
Кроме того:
return redirect('some_url', backend=backend, dataform.cleaned_data)
url(r'^link/$', some-view-name)
def some-view-name(request, backend, data):
все еще NoReverseMatch. Но в django-регистрации я видел что-то вроде этого:
url(r'^register/$',register,{'backend': 'registration.backends.default.DefaultBackend'}, name='registration_register'),
def register(request, backend, success_url=None, form_class=None,
disallowed_url='registration_disallowed',
template_name='user/login_logout_register/registration_form.html',
extra_context=None):
Ответы
Ответ 1
Во-первых, ваше определение URL-адреса вообще не принимает никаких параметров. Если вы хотите, чтобы параметры передавались из URL-адреса в представление, вам необходимо определить их в urlconf.
Во-вторых, это совсем не ясно, что вы ожидаете от словаря cleaned_data. Не забывайте, что вы не можете перенаправлять на POST - это ограничение HTTP, а не Django, поэтому ваш cleaned_data должен быть URL-параметром (ужасным) или, что несколько лучше, рядом параметров GET, поэтому URL-адрес будет выглядеть следующим образом:
/link/mybackend/?field1=value1&field2=value2&field3=value3
и т.д. В этом случае поле1, поле2 и поле3 не включаются в определение URLconf - они доступны в представлении через request.GET
.
Итак, ваш urlconf будет:
url(r'^link/(?P<backend>\w+?)/$', my_function)
и вид будет выглядеть так:
def my_function(request, backend):
data = request.GET
и обратное будет (после импорта urllib
):
return "%s?%s" % (redirect('my_function', args=(backend,)),
urllib.urlencode(form.cleaned_data))
Отредактировано после комментария
Весь смысл использования перенаправления и реверса, как вы делали, заключается в том, что вы переходите к URL-адресу - он возвращает Http-код, который заставляет браузер перенаправляться на новый URL-адрес и вызывает это.
Если вы просто хотите вызвать представление из своего кода, просто сделайте это напрямую - не нужно вообще использовать реверс.
Тем не менее, если все, что вы хотите сделать, это сохранить данные, просто поставьте его в сеанс:
request.session['temp_data'] = form.cleaned_data
Ответ 2
urls.py:
#...
url(r'element/update/(?P<pk>\d+)/$', 'element.views.element_update', name='element_update'),
views.py:
from django.shortcuts import redirect
from .models import Element
def element_info(request):
# ...
element = Element.object.get(pk=1)
return redirect('element_update', pk=element.id)
def element_update(request, pk)
# ...