Istniejące odpowiedzi świetnie spisały się wyjaśniając, co z tą reverse()
funkcją w Django.
Miałem jednak nadzieję, że moja odpowiedź rzuci inne światło na to, dlaczego : dlaczego używać reverse()
zamiast innych, bardziej prostych, prawdopodobnie bardziej pythonowych podejść w wiązaniu widoku szablonu, i jakie są uzasadnione powody popularności tego przekierowania za pośrednictwem reverse()
wzorzec ”w logice routingu Django.
Jedną z kluczowych korzyści jest odwrotna konstrukcja adresu URL, jak wspomniali inni. Podobnie jak chcesz {% url "profile" profile.id %}
wygenerować adres URL z pliku konfiguracyjnego adresu URL aplikacji: np path('<int:profile.id>/profile', views.profile, name="profile")
.
Ale, jak zauważył PO, użycie reverse()
jest również często łączone z użyciem HttpResponseRedirect
. Ale dlaczego?
Nie jestem do końca pewien, co to jest, ale jest używane razem z HttpResponseRedirect. Jak i kiedy ma być używana funkcja reverse ()?
Rozważ następujące kwestie views.py
:
from django.http import HttpResponseRedirect
from django.urls import reverse
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected = question.choice_set.get(pk=request.POST['choice'])
except KeyError:
# handle exception
pass
else:
selected.votes += 1
selected.save()
return HttpResponseRedirect(reverse('polls:polls-results',
args=(question.id)
))
A nasze minimalne urls.py
:
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('<int:question_id>/results/', views.results, name='polls-results'),
path('<int:question_id>/vote/', views.vote, name='polls-vote')
]
W vote()
funkcji kod w naszym else
bloku używa reverse
wraz z HttpResponseRedirect
następującym wzorem:
HttpResponseRedirect(reverse('polls:polls-results',
args=(question.id)
To przede wszystkim oznacza, że nie musimy kodować adresu URL na stałe (zgodnie z zasadą DRY), ale co bardziej istotne, reverse()
zapewnia elegancki sposób konstruowania ciągów adresów URL poprzez obsługę wartości rozpakowanych z argumentów ( args=(question.id)
jest obsługiwany przez URLConfig). Nałożony question
ma atrybut, id
który zawiera wartość 5
, adres URL skonstruowany na podstawie reverse()
będzie wtedy:
'/polls/5/results/'
W normalnym kodzie wiązania widoku szablonu używamy HttpResponse()
lub, render()
ponieważ zazwyczaj wymagają one mniej abstrakcji: jedna funkcja widoku zwraca jeden szablon:
def index(request):
return render(request, 'polls/index.html')
Ale w wielu uzasadnionych przypadkach przekierowania zazwyczaj zależy nam na zbudowaniu adresu URL z listy parametrów. Obejmują one przypadki takie jak:
- Przesyłanie formularza HTML za pośrednictwem
POST
żądania
- Potwierdzenie logowania użytkownika
- Zresetuj hasło za pomocą tokenów internetowych JSON
Większość z nich wymaga przekierowania i adresu URL zbudowanego na podstawie zestawu parametrów. Mam nadzieję, że to dodaje do już pomocnego wątku odpowiedzi!
url--> view name
. Ale czasami, tak jak podczas przekierowywania, musisz iść w odwrotnym kierunku i podać Django nazwę widoku, a Django generuje odpowiedni adres URL. Innymi słowyview name --> url
. To znaczyreverse()
(jest odwrotnością funkcji url). Nazwanie go może wydawać się bardziej przejrzyste,generateUrlFromViewName
ale jest to zbyt długie i prawdopodobnie niewystarczająco ogólne: docs.djangoproject.com/en/dev/topics/http/urls/…