Django возвращает redirect () с параметрами


83

В моей функции просмотра я хочу вызвать другое представление и передать ему данные:

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-адрес, если необходимо)? И backend, и 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-registration я видел что-то вроде этого:

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):

Ответы:


66

Во-первых, ваше определение URL-адреса вообще не принимает никаких параметров. Если вы хотите, чтобы параметры передавались из URL-адреса в представление, вам необходимо определить их в urlconf.

Во-вторых, совсем не ясно, что вы ожидаете от словаря cleaned_data. Не забывайте, что вы не можете перенаправить на POST - это ограничение HTTP, а не Django - поэтому ваши cleaned_data должны быть либо параметром URL (ужасно), либо, что немного лучше, серией параметров GET - так что URL будет в форме:

/link/mybackend/?field1=value1&field2=value2&field3=value3

и так далее. В этом случае field1, field2 и field3 не включены в определение 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

и если я не буду работать с cleaned_data в этом представлении, а просто передам его для дальнейшего использования? У меня много полей в dict cleaned_data, поэтому я бы не хотел передавать их как строку для получения :)
— muntu

Я не понимаю этого комментария. Пожалуйста, объясните более подробно, при необходимости обновив свой вопрос.
— Daniel Roseman

это второе представление будет хранить только эти отправленные данные для дальнейшего использования. Но вы уверены, что мне нужно указать для этого URL? Из документов похоже, что я просто вызываю представление напрямую. Также я надеялся просто отправить словарь с бэкэндом и данными в redirect () (как это делается в django-registration), а затем в URL-адресе (как этот dict в функции регистрации), но из того, что я вижу, это невозможно?
— muntu 09

да да да вот оно что !! Я потратил на это столько времени, полностью забыв о сессиях: / блин, спасибо !!
— muntu 09

1
Хороший момент в том, чтобы просто вызвать функцию, если URL-адрес не нужен.
— maxbellec

60

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)
    # ...
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.