2012-02-28 18 views
7

Było już kilka podobnych pytań, ale nie mogłem znaleźć odpowiedzi na mój problem po spędzeniu wielu godzin.Przekierowanie django() z parametrami

W poniższym kodzie, gdy przekierowuję do "anotherView" z "myView" z parametrem "username", działa poprawnie zgodnie z oczekiwaniami. Ale muszę również uwzględnić parametr "zasięg" w tym przekierowaniu, ponieważ ten "zakres" jest wymagany w przypadku szablonu używanego po przekierowaniu. Ilekroć próbuję zrobić, mam kilka błędów takich jak:

- „Nie mieszać * args i ** kwargs w zaproszeniu do odwrócenia()”

Czy istnieje sposób, aby poradzić sobie z tym tak jak ja chcieć?

def myView(request): 
     if request.user.is_authenticated(): 
     if request.method == 'POST': 
       #my code comes here 
       .... 
       return redirect('anotherView', username=request.user.username, {"range": range(int(layout))}) 



    def anotherView(request,username): 
     if request.user.is_authenticated(): 
     #my code comes here 
      .... 
      return redirect(something) 

Odpowiedz

20

redirect to jedynie opakowanie o numerze HttpResponseRedirect, które automatycznie wywołuje reverse, aby utworzyć adres URL, do którego ma nastąpić przekierowanie. W rezultacie parametry, które do niego przesyłasz, nie są arbitralne, muszą być takie same, jakie przechodzą na reverse, a konkretnie tylko te wymagane do utworzenia adresu URL.

Wiele osób zdaje się mieć problem ze zrozumieniem, że dane nie mogą być arbitralnie przekazywane do widoku. HTTP jest protokołem bezstanowym: każde żądanie istnieje na własną rękę, tak jakby użytkownik nigdy nie był na żadnej innej stronie witryny. Koncepcja sesji została stworzona, aby zapewnić poczucie "stanu" spójnej jednostce, takiej jak strona. W przypadku sesji dane są przechowywane w pewnej formie trwałej pamięci masowej, a "klucz" do wyszukiwania tych danych jest przekazywany klientowi (zazwyczaj przeglądarce użytkownika). Po załadowaniu następnej strony klient przesyła klucz z powrotem do serwera, a serwer używa go do wyszukiwania danych, aby uzyskać wygląd stanu.

W rezultacie, jeśli potrzebujesz danych z jednego widoku dostępnego w innym, musisz dodać go do sesji, wykonać przekierowanie i wyszukać dane w sesji z następnego widoku.

+0

dzięki za inny punkt widzenia. Mógłbym użyć tego sposobu, aby jakoś rozwiązać problem. – mco

+1

Świetnie! A oto dokumentacja Django na sesjach: https://docs.djangoproject.com/en/1.5/topics/http/sessions/ –

+0

Nie mogę edytować komentarza na sesjach @ Régis B., ale wersja 1.5 już teraz daje 404. Tutaj jest 1,11. https://docs.djangoproject.com/en/1.11/topics/http/sessions/ – LOlliffe

0

Przekierowanie przyjmuje nazwę widoku do przekierowania oraz wszelkie atrybuty przekazywane do innego widoku. W twoim przypadku anotherView ma tylko dwa parametry - żądanie i nazwę użytkownika, ale w przekierowaniu przekazujesz do niego więcej informacji.

Można spróbować czegoś takiego:

def anotherView(request, username, *args, **kwargs): 
    ... 

który pozwoli Ci przekazać więcej atrybutów do niego.

Edit

Jak o tym w oryginalnym widzenia:

kwargs = {"range": range(int(layout))} 
return redirect('anotherView', username=request.user.username, **kwargs) 
+0

Wciąż dostaję "non-arg słowa kluczowego po słowie kluczowym arg" lub „Nie mieszać * args i ** kwargs w wywołaniu do odwrócenia() "błędy nadal, nawet jeśli dodaję * args, ** kwargs – mco

+0

sprawdź zaktualizowaną odpowiedź – miki725

+0

nop nadal błąd, ale inny. tym razem przekierowanie nie może znaleźć widoku "anotherView", więc pokazuje "błąd nie znalezionego adresu URL" – mco

0

Co chcesz przekazać zmienną "zasięg" do? inna perspektywa? Nie ma parametru, który by to zaakceptował. Myślę, że możesz potrzebować funkcji reverse(), ale trudno powiedzieć.

+0

Zmienna "zakres" jest używana w szablonie innego widoku. Mam na myśli to, że kiedy nowy szablon jest ładowany po przekierowaniu, potrzebuję zasięgu. Ale nie chcę wstawiać zmiennej "zakres" w adresie URL, dlatego nie umieszczam jej jako parametru widoku "anotherView". Mam nadzieję, że jestem jasny? – mco

+0

Nie musi to być adres URL, ale będziesz potrzebował jakiegoś sposobu akceptowania tej zmiennej w parametrach innego widoku, albo przez podanie jej lub użycie argumentu * args, ** kwargs jak sugeruje miki725. – Tom

2

Zamiast przekierowanie do docelowego adresu URL, wystarczy wywołać funkcję widok docelowy bezpośrednio:

def myView(request): 
    if request.user.is_authenticated(): 
     if request.method == 'POST': 
      #my code comes here 
      .... 
      return anotherView(request, username, range) 



def anotherView(request,username,range): 
    if request.user.is_authenticated(): 
     #my code comes here 
     .... 
     return HttpResponse(something) 
+2

Dlaczego zostało to odrzucone? – Niklas

+5

Downvoted b/c, jeśli zrobisz to w ten sposób, a ktoś uderzy w przycisk odświeżania, twoje dane zostaną ponownie wysłane POST, co jest kiepską praktyką. – mikeb