Django gibt redirect () mit Parametern zurück

81

In meiner Ansichtsfunktion möchte ich eine andere Ansicht aufrufen und Daten an diese übergeben:

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

, wobei das Backend das Objekt register.backends ist und form.cleaned_data ein Diktat der Formulardaten ist (beide müssen jedoch entweder als * args oder ** kwargs gesendet werden, um Don't mix *args and **kwargs in call to reverse()!Fehler zu vermeiden ). Nach dem, was ich in den Dokumenten gefunden habe:

def my_view(request):
    ...
    return redirect('some-view-name', foo='bar')

Es sieht so aus, als müsste ich das Argument 'some-view-name' angeben, aber ist es nur der Name der Ansichtsfunktion oder der Name der URL? Deshalb möchte ich es ähnlich machen wie bei der Django-Registrierung, wobei:

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', (), {})

Ok, kann ich jetzt direkt meine Ansichtsfunktion aufrufen oder muss ich eine URL dafür angeben? Und was ist wichtiger, wie sollte mein Funkanruf (und ggf. eine URL) aussehen? Sowohl das Backend als auch die bereinigten Daten werden für eine spätere Verwendung nur durch diese Ansicht geleitet. Ich habe es versucht, aber es ist unangemessen:

url(r'^link/$', some-view-name)   
def some-view-name(request, *args):

So gut wie das :

return redirect('some_url', backend=backend, dataform.cleaned_data) 
url(r'^link/$', some-view-name)    
def some-view-name(request, backend, data):

immer noch NoReverseMatch. Aber bei der Django-Registrierung habe ich so etwas gesehen:

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

Antworten:

66

Erstens akzeptiert Ihre URL-Definition überhaupt keine Parameter. Wenn Sie möchten, dass Parameter von der URL in die Ansicht übergeben werden, müssen Sie sie in der urlconf definieren.

Zweitens ist überhaupt nicht klar, was Sie mit dem Wörterbuch clean_data erwarten. Vergessen Sie nicht, dass Sie nicht zu einem POST umleiten können - dies ist eine Einschränkung von HTTP, nicht von Django -, daher müssen Ihre bereinigten_Daten entweder ein URL-Parameter (schrecklich) oder, etwas besser, eine Reihe von GET-Parametern sein - also die URL wäre in der Form:

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

und so weiter. In diesem Fall sind Feld1, Feld2 und Feld3 nicht in der URLconf-Definition enthalten - sie sind in der Ansicht über verfügbar request.GET.

Ihre URL wäre also:

url(r'^link/(?P<backend>\w+?)/$', my_function)

und die Aussicht würde aussehen wie:

def my_function(request, backend):
   data = request.GET

und das Gegenteil wäre (nach dem Import urllib):

return "%s?%s" % (redirect('my_function', args=(backend,)),
                  urllib.urlencode(form.cleaned_data))

Nach Kommentar bearbeitet

Der springende Punkt bei der Verwendung von Umleitung und Umkehrung ist, wie Sie es getan haben, dass Sie zur URL wechseln - es wird ein HTTP-Code zurückgegeben, der den Browser veranlasst, zur neuen URL umzuleiten und diese aufzurufen.

Wenn Sie die Ansicht einfach aus Ihrem Code heraus aufrufen möchten, tun Sie dies einfach direkt - Sie müssen die Umkehrung überhaupt nicht verwenden.

Das heißt, wenn Sie die Daten nur speichern möchten, fügen Sie sie einfach in die Sitzung ein:

request.session['temp_data'] = form.cleaned_data
Daniel Roseman
quelle
und wenn ich in dieser Ansicht nicht mit bereinigten_Daten arbeite, sondern sie nur zur späteren Verwendung weitergebe? Ich habe viele Felder im Diktat "Cleaned_Data", daher möchte ich vermeiden, sie als Get-String zu übergeben :)
Muntu
Ich verstehe diesen Kommentar nicht. Bitte erläutern Sie dies genauer und aktualisieren Sie gegebenenfalls Ihre Frage.
Daniel Roseman
In dieser zweiten Ansicht werden diese gesendeten Daten nur zur weiteren Verwendung gespeichert. Aber sind Sie sicher, dass ich eine URL dafür angeben muss? Aus den Dokumenten geht hervor, dass ich die Ansicht nur direkt aufrufe. Ich hatte auch gehofft, nur ein Wörterbuch mit Backend und Daten in redirect () (wie bei der Django-Registrierung) und dann in der URL (wie dieses Diktat in der Registerfunktion) zu senden, aber soweit ich das sehe, ist es unmöglich?
Muntu
ja ja ja das wars !! Ich habe so viel Zeit damit verschwendet, Sitzungen komplett zu vergessen: / verdammt, danke !!
Muntu
1
Ein guter Punkt, um nur die Funktion aufzurufen, wenn man die URL nicht benötigt.
Maxbellec
57

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)
    # ...
sergi0
quelle