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.