Come posso ottenere l'URL completo / assoluto (ad es. https://example.com/some/path
) In Django senza il modulo Sites ? È solo stupido ... Non dovrei aver bisogno di interrogare il mio DB per afferrare l'URL!
Voglio usarlo con reverse()
.
Come posso ottenere l'URL completo / assoluto (ad es. https://example.com/some/path
) In Django senza il modulo Sites ? È solo stupido ... Non dovrei aver bisogno di interrogare il mio DB per afferrare l'URL!
Voglio usarlo con reverse()
.
Risposte:
Usa il pratico metodo request.build_absolute_uri () su richiesta, passagli l'URL relativo e te ne darà uno completo.
Per impostazione predefinita, request.get_full_path()
viene restituito l' URL assoluto per , ma è possibile passargli un URL relativo come primo argomento per convertirlo in un URL assoluto.
{{ request.build_absolute_uri }}{{ object.get_absolute_url }}
- e heyho, url completo.
{% if request.is_secure %}https://{% else %}http://{% endif %}{{ request.get_host }}{{ object.get_absolute_url }}
perché {{ request.build_absolute_uri }}
aveva una barra finale e ho {{ object.get_absolute_url }}
iniziato con una barra con conseguente doppia barra nell'URL.
Se vuoi usarlo con reverse()
puoi farlo:request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))
url_name
invece di view_name
)
def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)
È inoltre possibile utilizzare get_current_site
come parte dell'app dei siti ( from django.contrib.sites.models import get_current_site
). Prende un oggetto richiesta e, per impostazione predefinita, SITE_ID
viene impostato l'oggetto sito configurato in settings.py, se richiesto None
. Maggiori informazioni nella documentazione per l' utilizzo del framework dei siti
per esempio
from django.contrib.sites.shortcuts import get_current_site
request = None
full_url = ''.join(['http://', get_current_site(request).domain, obj.get_absolute_url()])
Non è compatto / pulito come request.build_absolute_url()
, ma è utilizzabile quando gli oggetti richiesta non sono disponibili e hai un URL del sito predefinito.
django.contrib.sites
nel tuo INSTALLED_APPS
, non colpirà affatto il DB e fornirà informazioni basate sull'oggetto Request (vedi get_current_site )
build_absolute_uri
sembra comunque la soluzione più semplice e pulita.
Se non riesci ad accedere, request
non puoi utilizzare get_current_site(request)
come raccomandato in alcune soluzioni qui. È invece possibile utilizzare una combinazione del framework dei siti nativo get_absolute_url
. Imposta almeno un sito nell'amministratore, assicurati che il tuo modello abbia un nell'amministratore metodo get_absolute_url () , quindi:
>>> 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
a None
o chiamare get_current_site(None)
.
Se non si desidera colpire il database, è possibile farlo con un'impostazione. Quindi, utilizzare un processore di contesto per aggiungerlo a ogni modello:
# 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
Se stai cercando di farlo in un modello Django, ho rilasciato un piccolo pacchetto PyPI django-fullurl
per permetterti di sostituire url
e static
tag modello con fullurl
e fullstatic
, in questo modo:
{% load fullurl %}
Absolute URL is: {% fullurl "foo:bar" %}
Another absolute URL is: {% fullstatic "kitten.jpg" %}
Si spera che questi badge rimangano aggiornati automaticamente:
In una vista, puoi ovviamente usare request.build_absolute_uri
invece.
request
oggetto per ottenere il nome di dominio. In tal caso, è necessario utilizzare sites
invece il framework, che ottiene il nome di dominio dal database. Vedi django-absoluteuri
, menzionato nella sezione "vedi anche" del README di questo pacchetto PyPI.
Per creare un collegamento completo a un'altra pagina da un modello, è possibile utilizzare questo:
{{ request.META.HTTP_HOST }}{% url 'views.my_view' my_arg %}
request.META.HTTP_HOST fornisce il nome host e url fornisce il nome relativo. Il motore modello quindi li concatena in un URL completo.
http
in questo contesto) e ://
parte dell'URL, quindi non fornirà un URL completo .
Ancora un altro modo. Puoi usarlo build_absolute_uri()
nel tuo view.py
e passarlo al modello.
view.py
def index(request):
baseurl = request.build_absolute_uri()
return render_to_response('your-template.html', { 'baseurl': baseurl })
your-template.html
{{ baseurl }}
HttpRequest.build_absolute_uri(request)
è equivalente a request.build_absolute_uri()
non è vero?
Esamina il Request.META
dizionario che arriva. Penso che abbia il nome del server e la porta del server.
Questo ha funzionato per me nel mio modello:
{{ request.scheme }}:{{ request.META.HTTP_HOST }}{% url 'equipos:marca_filter' %}
Avevo bisogno dell'URL completo per passarlo a una funzione di recupero js. Spero che questo ti sia d'aiuto.
So che questa è una vecchia domanda. Ma penso che la gente si imbatta ancora molto in questo.
Ci sono un paio di librerie là fuori che integrano la funzionalità predefinita di Django. Ne ho provati alcuni. Mi piace la seguente libreria quando si fa riferimento inverso a URL assoluti:
https://github.com/fusionbox/django-absoluteuri
Un altro che mi piace perché puoi facilmente mettere insieme un dominio, un protocollo e un percorso è:
https://github.com/RRMoelker/django-full-url
Questa libreria consente di scrivere semplicemente ciò che si desidera nel modello, ad esempio:
{{url_parts.domain}}
Se si utilizza il framework REST di django, è possibile utilizzare la funzione inversa da rest_framework.reverse
. Questo ha lo stesso comportamento di django.core.urlresolvers.reverse
, tranne per il fatto che utilizza un parametro di richiesta per creare un URL completo.
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,))
Modificato per menzionare la disponibilità solo nel framework REST
request=request
. Inoltre, non sembra che la richiesta sia documentata qui docs.djangoproject.com/en/1.9/ref/urlresolvers/#reverse
Capito:
wsgiref.util.request_uri(request.META)
Ottieni l'uri completo con schema, host, percorso della porta e query.
Vi è anche ABSOLUTE_URL_OVERRIDES disponibile come impostazione
https://docs.djangoproject.com/en/2.1/ref/settings/#absolute-url-overrides
Ma questo sostituisce get_absolute_url (), che potrebbe non essere desiderabile.
Invece di installare framework di siti solo per questo o fare alcune delle altre cose menzionate qui che si basano sull'oggetto richiesta, penso che la soluzione migliore sia quella di collocare questo in models.py
Definisci BASE_URL in settings.py, quindi importalo in models.py e crea una classe astratta (o aggiungila a quella che stai già utilizzando) che definisce get_truly_absolute_url (). Potrebbe essere semplice come:
def get_truly_absolute_url(self):
return BASE_URL + self.get_absolute_url()
Sottoclassalo e ora puoi usarlo ovunque.
Come menzionato in altre risposte, request.build_absolute_uri()
è perfetto se si ha accesso a request
, esites
framework è eccezionale fintanto che URL diversi puntano a database diversi.
Tuttavia, il mio caso d'uso era leggermente diverso. Il mio server di gestione temporanea e il server di produzione accedono allo stesso database, ma get_current_site
entrambi hanno restituito il primo site
nel database. Per risolvere questo problema, devi utilizzare un qualche tipo di variabile d'ambiente. Puoi usare 1) una variabile d'ambiente (qualcosa del genere os.environ.get('SITE_URL', 'localhost:8000')
) o 2) SITE_ID
s differenti per server diversi E settings.py diversi .
Eventualmente qualcuno lo troverà utile!
Mi sono imbattuto in questo thread perché stavo cercando di creare un URI assoluto per una pagina di successo. request.build_absolute_uri()
mi ha dato un URI per la mia vista corrente ma per ottenere l'URI per la mia vista di successo ho usato il seguente ...
request.build_absolute_uri (inversa ( 'success_view_name'))
Puoi anche usare:
import socket
socket.gethostname()
Questo funziona bene per me,
Non sono del tutto sicuro di come funzioni. Credo che questo sia un po 'più basso livello e restituirà il nome host del server, che potrebbe essere diverso dal nome host utilizzato dall'utente per accedere alla tua pagina.