Jak mogę uzyskać pełny / bezwzględny adres URL (np. https://example.com/some/path
) W Django bez modułu Witryny? ? To po prostu głupie ... Nie powinienem wysyłać zapytań do mojej bazy danych, aby złapać adres URL!
Chcę go używać z reverse()
.
Jak mogę uzyskać pełny / bezwzględny adres URL (np. https://example.com/some/path
) W Django bez modułu Witryny? ? To po prostu głupie ... Nie powinienem wysyłać zapytań do mojej bazy danych, aby złapać adres URL!
Chcę go używać z reverse()
.
Odpowiedzi:
Użyj poręcznej metody request.build_absolute_uri () na żądanie, przekaż jej względny adres URL, a otrzymasz pełny.
Domyślnie request.get_full_path()
zwracany jest bezwzględny adres URL dla , ale możesz przekazać mu względny adres URL jako pierwszy argument do przekonwertowania go na bezwzględny adres URL.
{{ request.build_absolute_uri }}{{ object.get_absolute_url }}
- i hejho, pełny adres URL.
{% if request.is_secure %}https://{% else %}http://{% endif %}{{ request.get_host }}{{ object.get_absolute_url }}
ponieważ {{ request.build_absolute_uri }}
miałem ukośnik i {{ object.get_absolute_url }}
zacząłem od ukośnika powodującego podwójne ukośniki w adresie URL.
Jeśli chcesz go używać, reverse()
możesz to zrobić:request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))
url_name
zamiast view_name
)
def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)
Możesz także użyć get_current_site
jako części aplikacji witryn ( from django.contrib.sites.models import get_current_site
). Pobiera obiekt żądania i domyślnie przyjmuje obiekt strony, który skonfigurowałeś SITE_ID
w pliku settings.py, jeśli jest to żądanie None
. Przeczytaj więcej w dokumentacji dla korzystania ze struktury witryn
na przykład
from django.contrib.sites.shortcuts import get_current_site
request = None
full_url = ''.join(['http://', get_current_site(request).domain, obj.get_absolute_url()])
Nie jest tak kompaktowy / schludny jak request.build_absolute_url()
, ale można go używać, gdy obiekty żądań są niedostępne i masz domyślny adres URL witryny.
django.contrib.sites
w INSTALLED_APPS
ogóle nie trafi do bazy danych i nie dostarczy informacji na podstawie obiektu żądania (patrz get_current_site )
build_absolute_uri
nadal wygląda na łatwiejsze i czystsze rozwiązanie.
Jeśli nie możesz uzyskać dostępu request
, nie możesz użyć tego, get_current_site(request)
co jest zalecane w niektórych rozwiązaniach tutaj. Zamiast tego możesz użyć kombinacji natywnej struktury Witryn get_absolute_url
. Skonfiguruj co najmniej jedną witrynę w adminie , upewnij się, że Twój model ma metodę get_absolute_url () , a następnie:
>>> from django.contrib.sites.models import Site
>>> domain = Site.objects.get_current().domain
>>> obj = MyModel.objects.get(id=3)
>>> path = obj.get_absolute_url()
>>> url = 'http://{domain}{path}'.format(domain=domain, path=path)
>>> print(url)
'http://example.com/mymodel/objects/3/'
https://docs.djangoproject.com/en/dev/ref/contrib/sites/#getting-the-current-domain-for-full-urls
request
do None
lub zadzwoń get_current_site(None)
.
Jeśli nie chcesz trafić do bazy danych, możesz to zrobić za pomocą ustawienia. Następnie użyj procesora kontekstu, aby dodać go do każdego szablonu:
# settings.py (Django < 1.9)
...
BASE_URL = 'http://example.com'
TEMPLATE_CONTEXT_PROCESSORS = (
...
'myapp.context_processors.extra_context',
)
# settings.py (Django >= 1.9)
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
# Additional
'myapp.context_processors.extra_context',
],
},
},
]
# myapp/context_processors.py
from django.conf import settings
def extra_context(request):
return {'base_url': settings.BASE_URL}
# my_template.html
<p>Base url is {{ base_url }}.</p>
django-fullurl
Jeśli próbujesz to zrobić w szablonie Django, wypuściłem niewielki pakiet PyPI, django-fullurl
który pozwala ci zamieniać url
i static
tagi szablonów na fullurl
i fullstatic
, tak:
{% load fullurl %}
Absolute URL is: {% fullurl "foo:bar" %}
Another absolute URL is: {% fullstatic "kitten.jpg" %}
Miejmy nadzieję, że te odznaki powinny być automatycznie aktualizowane:
W widoku możesz oczywiście użyć request.build_absolute_uri
zamiast tego.
request
obiektu, z którego można by uzyskać nazwę domeny. W takim przypadku powinieneś użyć sites
frameworka, który pobiera nazwę domeny z bazy danych. Patrz django-absoluteuri
wspomniany w sekcji „patrz także” w pliku README tego pakietu PyPI.
Aby utworzyć kompletny link do innej strony z szablonu, możesz użyć tego:
{{ request.META.HTTP_HOST }}{% url 'views.my_view' my_arg %}
request.META.HTTP_HOST podaje nazwę hosta, a adres URL podaje względną nazwę. Następnie silnik szablonów łączy je w pełny adres URL.
http
w tym kontekście) i ://
części adresu URL, więc nie poda pełnego adresu URL .
Jeszcze inny sposób. Możesz użyć build_absolute_uri()
w swoim view.py
i przekazać go do szablonu.
view.py
def index(request):
baseurl = request.build_absolute_uri()
return render_to_response('your-template.html', { 'baseurl': baseurl })
twój-szablon.html
{{ baseurl }}
HttpRequest.build_absolute_uri(request)
jest równoważne, request.build_absolute_uri()
prawda?
Sprawdź Request.META
słownik, który się pojawi. Myślę, że ma nazwę serwera i port serwera.
To zadziałało w moim szablonie:
{{ request.scheme }}:{{ request.META.HTTP_HOST }}{% url 'equipos:marca_filter' %}
Potrzebowałem pełnego adresu URL, aby przekazać go do funkcji pobierania js. Mam nadzieję, że ci to pomoże.
Wiem, że to stare pytanie. Ale myślę, że ludzie wciąż na to wpadają.
Istnieje kilka bibliotek, które uzupełniają domyślną funkcjonalność Django. Próbowałem kilka. Podoba mi się następująca biblioteka podczas odwrotnego odwoływania się do bezwzględnych adresów URL:
https://github.com/fusionbox/django-absoluteuri
Innym, który podoba mi się, ponieważ możesz łatwo połączyć domenę, protokół i ścieżkę, jest:
https://github.com/RRMoelker/django-full-url
Ta biblioteka pozwala po prostu napisać, co chcesz w szablonie, np .:
{{url_parts.domain}}
Jeśli używasz frameworka REST django, możesz użyć funkcji odwrotnej od rest_framework.reverse
. Zachowuje się tak samo jak django.core.urlresolvers.reverse
, z tym wyjątkiem, że używa parametru żądania do zbudowania pełnego adresu URL.
from rest_framework.reverse import reverse
# returns the full url
url = reverse('view_name', args=(obj.pk,), request=request)
# returns only the relative url
url = reverse('view_name', args=(obj.pk,))
Edytowano, aby wspomnieć o dostępności tylko w ramach REST
request=request
. Wydaje się również, że prośba nie jest udokumentowana tutaj docs.djangoproject.com/en/1.9/ref/urlresolvers/#reverse
Dostępne jest również ustawienie ABSOLUTE_URL_OVERRIDES
https://docs.djangoproject.com/en/2.1/ref/settings/#absolute-url-overrides
Ale to zastępuje get_absolute_url (), co może nie być pożądane.
Zamiast instalowania frameworku witryn tylko w tym celu lub wykonywania innych wymienionych tutaj czynności, które zależą od obiektu żądania, myślę, że lepszym rozwiązaniem jest umieszczenie tego w pliku models.py
Zdefiniuj BASE_URL w settings.py, a następnie zaimportuj go do models.py i utwórz klasę abstrakcyjną (lub dodaj ją do już używanej), która definiuje get_truly_absolute_url (). Może to być tak proste, jak:
def get_truly_absolute_url(self):
return BASE_URL + self.get_absolute_url()
Podklasuj go, a teraz możesz go używać wszędzie.
Jak wspomniano w innych odpowiedziach, request.build_absolute_uri()
jest idealny, jeśli masz dostęp do request
isites
struktura jest świetna, o ile różne adresy URL wskazują różne bazy danych.
Jednak mój przypadek użycia był nieco inny. Mój serwer pomostowy i serwer produkcyjny uzyskują dostęp do tej samej bazy danych, ale get_current_site
obie zwróciły pierwszą site
w bazie danych. Aby rozwiązać ten problem, musisz użyć jakiejś zmiennej środowiskowej. Możesz użyć 1) zmiennej środowiskowej (coś podobnego os.environ.get('SITE_URL', 'localhost:8000')
) lub 2) różnych SITE_ID
s dla różnych serwerów ORAZ różnych ustawień .py .
Mam nadzieję, że ktoś uzna to za przydatne!
Natknąłem się na ten wątek, ponieważ chciałem zbudować bezwzględny identyfikator URI strony sukcesu. request.build_absolute_uri()
dał mi identyfikator URI dla mojego obecnego widoku, ale aby uzyskać identyfikator URI dla mojego widoku sukcesu, użyłem następującego ...
request.build_absolute_uri (rewers („nazwa_widoku_uduktu”))
Możesz także użyć:
import socket
socket.gethostname()
To działa dobrze dla mnie,
Nie jestem do końca pewien, jak to działa. Uważam, że jest to nieco niższy poziom i zwróci nazwę hosta serwera, która może być inna niż nazwa hosta używana przez użytkownika w celu przejścia do strony.