Come posso ottenere l’URL completo / assoluto (con dominio) in Django?

Come posso ottenere l’URL completo / assoluto (ad es. https://example.com/some/path ) in Django senza il modulo Siti ? E ‘solo sciocco … Non avrei bisogno di interrogare il mio DB per aggirare l’URL!

Voglio usarlo con reverse() .

Usa il pratico metodo request.build_absolute_uri () su richiesta, passa l’url relativo e ti darà quello completo.

Per impostazione predefinita, viene restituito l’URL assoluto per request.get_full_path() , ma puoi passargli un URL relativo come primo argomento per convertirlo in un URL assoluto.

Se vuoi usarlo con reverse() puoi farlo: request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))

Puoi anche utilizzare get_current_site come parte dell’app dei siti ( from django.contrib.sites.models import get_current_site ). Richiede un object di richiesta e il valore predefinito è l’object del sito che è stato configurato con SITE_ID in settings.py se la richiesta è 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 è così compatto / ordinato come request.build_absolute_url() , ma è utilizzabile quando gli oggetti richiesta non sono disponibili e hai un URL di sito predefinito.

Se non è ansible accedere alla request non è ansible utilizzare get_current_site(request) come consigliato in alcune soluzioni qui. Puoi invece utilizzare una combinazione del framework Sites nativo e get_absolute_url . Imposta almeno un sito nell’admin , assicurati che il tuo modello abbia un 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

Se non vuoi colpire il database, puoi 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 

Base url is {{ base_url }}.

django-fullurl

Se stai provando a farlo in un modello Django, ho rilasciato un piccolo pacchetto PyPI django-fullurl per permetterti di sostituire static tag di template url e static con fullurl e fullstatic , come questo:

 {% load fullurl %} Absolute URL is: {% fullurl "foo:bar" %} Another absolute URL is: {% fullstatic "kitten.jpg" %} 

Si spera che questi badge si aggiornino automaticamente:

PyPI Travis CI

In una vista, puoi ovviamente usare request.build_absolute_uri .

Per creare un collegamento completo a un’altra pagina da un modello, puoi 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 di template quindi li concatena in un URL completo.

Esaminare il dizionario Request.META fornito. Penso che abbia il nome del server e la porta del server.

Ancora un altro modo. Puoi usare 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 }} 

Secondo te, fai questo:

 base_url = "{0}://{1}{2}".format(request.scheme, request.get_host(), request.path) 

So che questa è una vecchia domanda. Ma penso che la gente ci si imbatta molto in questo.

Ci sono un paio di librerie là fuori che completano la funzionalità Django predefinita. Ho provato alcuni. Mi piace la seguente libreria quando si fa riferimento all’invio di URL assoluti:

https://github.com/fusionbox/django-absoluteuri

Un altro mi piace perché si può facilmente mettere insieme un dominio, protocollo e percorso è:

https://github.com/RRMoelker/django-full-url

Questa libreria ti consente di scrivere semplicemente ciò che desideri nel tuo modello, ad esempio:

 {{url_parts.domain}} 

Prova il seguente codice:

 {{ request.scheme }}://{{ request.META.HTTP_HOST }} 

Se stai usando il framework REST di django, puoi usare 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

Capito:

 wsgiref.util.request_uri(request.META) 

Ottieni l’intero uri con schema, host, percorso della porta e query.

request.get_host() ti darà il dominio.

Puoi provare “request.get_full_path ()”

Puoi anche usare:

 import socket socket.gethostname() 

Funziona bene per me,

Non sono completamente sicuro di come funzioni. Credo che questo livello sia un po ‘più basso e restituirà il nome host del tuo server, che potrebbe essere diverso dal nome host utilizzato dall’utente per accedere alla tua pagina.