Jak uzyskać nazwę domeny mojej bieżącej witryny z szablonu Django? Próbowałem poszukać w tagu i filtrach, ale nic tam nie ma.
python
django
django-templates
Jean-François Fabre
źródło
źródło
request.META['HTTP_HOST']
daje Ci domenę. W szablonie byłoby to{{ request.META.HTTP_HOST }}
.Host:
nagłówek i otrzyma odpowiedź z fałszywą domeną gdzieś na stronie, w jaki sposób tworzy to lukę w zabezpieczeniach? Nie rozumiem, czym różni się to od tego, że użytkownik pobiera wygenerowany kod HTML i modyfikuje się przed przesłaniem go do własnej przeglądarki.Jeśli chcesz uzyskać rzeczywisty nagłówek hosta HTTP, zobacz komentarz Daniela Rosemana na temat odpowiedzi @ Phsiao. Inną alternatywą jest to, że jeśli korzystasz z platformy contrib.sites , możesz ustawić kanoniczną nazwę domeny dla Witryny w bazie danych (mapowanie domeny żądania do pliku ustawień z odpowiednim SITE_ID jest czymś, co musisz zrobić samodzielnie za pośrednictwem konfiguracja serwera WWW). W takim przypadku szukasz:
musiałbyś sam umieścić obiekt current_site w kontekście szablonu, jeśli chcesz go użyć. Jeśli używasz go wszędzie, możesz to spakować w procesorze kontekstu szablonu.
źródło
SITE_ID
ustawienie jest równeid
atrybutowi bieżącej witryny w aplikacji Witryny (można ją znaleźćid
w panelu administracyjnym Witryny). Kiedy dzwoniszget_current
, Django pobiera twójSITE_ID
i zwracaSite
obiekt z tym id z bazy danych.print("get_current_site: ", get_current_site(request)) print("absolute uri: ", request.build_absolute_uri()) print("HTTP_HOST: ", request.META['HTTP_HOST']) get_current_site: localhost:8001 absolute uri: http://localhost:8001/... HTTP_HOST: localhost:8001
Odkryłem
{{ request.get_host }}
metodę.źródło
HTTP_X_FORWARDED_HOST
nagłówek HTTP.request.build_absolute_uri
( docs.djangoproject.com/en/dev/ref/request-response/ ... )Uzupełniając Carla Meyera, możesz zrobić taki procesor kontekstu:
module.context_processors.py
local settings.py
settings.py
szablony zwracające wystąpienie kontekstu witryna url to {{SITE_URL}}
możesz napisać własną rutynę, jeśli chcesz obsługiwać subdomeny lub SSL w procesorze kontekstu.
źródło
Odmiana używanego przeze mnie procesora kontekstu to:
SimpleLazyObject
Wrapper pilnuje wywołanie DB dzieje się tylko wtedy, gdy szablon faktycznie korzysta zsite
obiektu. Spowoduje to usunięcie zapytania ze stron administratora. Zapisuje również wynik w pamięci podręcznej.i uwzględnij to w ustawieniach:
W szablonie możesz użyć,
{{ site.domain }}
aby uzyskać aktualną nazwę domeny.edycja: aby obsługiwać również przełączanie protokołów, użyj:
źródło
SimpleLazyObject
tutaj używać , ponieważ lambda nie zostanie wywołana, jeśli i tak nic nie uzyska dostępu do „witryny”.SimpleLazyObject
, każdyRequestContext
zadzwoniget_current_site()
, a tym samym wykona zapytanie SQL. Opakowanie zapewnia, że zmienna jest oceniana tylko wtedy, gdy jest faktycznie używana w szablonie.SimpleLazyObject
to na celu uniknięcie ponownej oceny funkcji, która nie jest tak naprawdę potrzebna, ponieważSite
obiekt jest buforowany.from django.contrib.sites.shortcuts import get_current_site
Wiem, że to pytanie jest stare, ale natknąłem się na nie, szukając pythonowego sposobu na uzyskanie bieżącej domeny.
źródło
build_absolute_uri
jest udokumentowane tutaj .Szybki i prosty, ale nie nadaje się do produkcji:
(w widoku)
(w szablonie)
Pamiętaj, aby użyć RequestContext , co ma miejsce, jeśli używasz renderowania .
Nie ufaj
request.META['HTTP_HOST']
produkcji: te informacje pochodzą z przeglądarki. Zamiast tego użyj odpowiedzi @ CarlMeyerźródło
request.scheme
. Być może dostępne tylko w nowszych wersjach django.request.scheme
został dodany w Django 1.7.{{ request.get_host }}
powinien chronić przed atakami nagłówka HTTP Host, gdy jest używany razem zALLOWED_HOSTS
ustawieniem (dodane w Django 1.4.4).Pamiętaj, że
{{ request.META.HTTP_HOST }}
nie ma takiej samej ochrony. Zobacz dokumentację :Jeśli chodzi o używanie
request
w twoim szablonie, wywołania funkcji renderującej szablon zmieniły się w Django 1.8 , więc nie musisz już obsługiwaćRequestContext
bezpośrednio.Oto jak wyrenderować szablon widoku za pomocą funkcji skrótu
render()
:Oto jak renderować szablon wiadomości e-mail, który IMO jest najczęstszym przypadkiem, w którym chcesz uzyskać wartość hosta:
Oto przykład dodawania pełnego adresu URL w szablonie wiadomości e-mail; request.scheme powinien otrzymać
http
lub whttps
zależności od tego, czego używasz:źródło
Używam niestandardowego tagu szablonu. Dodaj np .
<your_app>/templatetags/site.py
:Użyj go w szablonie takim jak ten:
źródło
get_current
jest udokumentowaną metodą: docs.djangoproject.com/en/dev/ref/contrib/sites/…'http://%s'
może być problem w przypadkuhttps
połączenia; schemat nie jest dynamiczny w tym przypadku.Podobnie jak w przypadku odpowiedzi użytkownika panchicore, oto co zrobiłem na bardzo prostej stronie internetowej. Udostępnia kilka zmiennych i udostępnia je w szablonie.
SITE_URL
trzymałby wartość podobną doexample.com
SITE_PROTOCOL
trzymałby wartość podobnąhttp
lubhttps
SITE_PROTOCOL_URL
trzymałby wartość podobnąhttp://example.com
lubhttps://example.com
SITE_PROTOCOL_RELATIVE_URL
trzymałby wartość podobną//example.com
.module / context_processors.py
settings.py
Następnie na szablonach, należy je jak
{{ SITE_URL }}
,{{ SITE_PROTOCOL }}
,{{ SITE_PROTOCOL_URL }}
i{{ SITE_PROTOCOL_RELATIVE_URL }}
źródło
W szablonie Django możesz:
źródło
django.template.context_processors.request
także [ten poradnik pomógł] ( simpleisbetterthancomplex.com/tips/2016/07/20/… )Jeśli używasz procesora kontekstu „żądania” i korzystasz ze struktury witryn Django i masz zainstalowane oprogramowanie pośrednie witryny (tj. Twoje ustawienia obejmują te):
... wtedy obiekt będzie
request
dostępny w szablonach i będzie zawierał odniesienie do aktualnegoSite
żądania jakorequest.site
. Następnie możesz pobrać domenę w szablonie za pomocą:źródło
A co z tym podejściem? Pracuje dla mnie. Jest również używany w rejestracji django .
źródło
localhost
przyniesie cihttps
schemat (jest uważany za bezpieczny), który nie zadziała, jeśli masz statyczny adres URL (tylkohttp://127.0.0.1
jest prawidłowy, niehttps://127.0.0.1
). Więc nie jest idealny, gdy jest jeszcze w fazie rozwoju.źródło
Możesz użyć
{{ protocol }}://{{ domain }}
w swoich szablonach, aby uzyskać nazwę domeny.źródło