Django повертає перенаправлення () з параметрами


83

У своїй функції перегляду я хочу викликати інший вигляд і передати йому дані:

return redirect('some-view-name', backend, form.cleaned_data)

, де бекенд - це об’єкт 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-реєстрації, де:

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-адреса, якщо потрібно)? І серверні дані, і очищені дані просто передаються через цей подання для подальшого використання. Я спробував це, але це неправильно:

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

Відповіді:


66

По-перше, ваше визначення URL-адреси взагалі не приймає жодних параметрів. Якщо ви хочете, щоб параметри передавалися з URL-адреси у подання, вам потрібно визначити їх у urlconf.

По-друге, зовсім незрозуміло, що ви очікуєте зі словником clean_data. Не забувайте, що ви не можете перенаправляти на POST - це обмеження HTTP, а не Django - тому ваші очищені дані повинні бути параметром 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

і якщо я не буду оперувати очищеними даними в цьому поданні, а просто передати їх для подальшого використання? У мене є багато полів у дикті очищених даних, тому я хотів би уникати їх передачі як рядок отримання :)
muntu

Я не розумію цей коментар. Будь ласка, поясніть детальніше, при необхідності оновивши своє питання.
Даніель Роузман,

це друге представлення буде зберігати ці надіслані дані лише для подальшого використання. Але ви впевнені, що мені потрібно вказати URL-адресу для цього? З документації схоже, що я просто дзвоню безпосередньо до подання. Також я сподівався просто надіслати словник із серверною базою та даними у redirect () (як це робиться в django-реєстрації), а потім у url (як цей дикт у функції реєстрації), але з того, що я бачу, це неможливо?
muntu

так так так це !! Я витратив стільки часу на це, повністю забувши про сеанси: / блін, дякую !!
muntu

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.