444 votes

Comment puis-je obtenir l'URL complète/absolue (avec le domaine) dans Django ?

Comment puis-je obtenir l'URL complète/absolue (par ex. https://example.com/some/path ) dans Django sans le module Sites ? C'est tout simplement idiot... Je ne devrais pas avoir besoin d'interroger ma base de données pour récupérer l'URL !

Je veux l'utiliser avec reverse() .

13 votes

Pour l'anecdote : Le module sites ne consulte la base de données que la première fois qu'il a besoin du nom du site, le résultat est mis en cache dans une variable de module (SITE_CACHE) qui restera en place jusqu'à la recompilation du module ou jusqu'à ce que la méthode SiteManager.clear_cache() soit appelée. Voir : code.djangoproject.com/svn/django/tags/releases/1.3/django/

595voto

Dmitry Shevchenko Points 11398

Utiliser des outils pratiques request.build_absolute_uri() à la demande, transmettez-lui l'url relative et il vous donnera l'url complète.

Par défaut, l'URL absolue de request.get_full_path() est renvoyée, mais vous pouvez lui fournir une URL relative comme premier argument pour la convertir en URL absolue.

>>> request.build_absolute_uri()
'https://example.com/music/bands/the_beatles/?print=true'
>>> request.build_absolute_uri('/bands/?print=true')
'https://example.com/bands/?print=true'

0 votes

+1 Cette fonction utilise les mêmes données que celles de ma réponse. Et c'est certainement une option plus pratique.

3 votes

Qu'en est-il de l'url : localhost/home/#/test ? Je ne vois que localhost/home . Comment puis-je voir la partie après pointu ?

49 votes

Tout ce qui suit # n'est pas transmis au serveur, il s'agit d'une fonctionnalité réservée au navigateur

121voto

blobmarket Points 261

Si vous souhaitez l'utiliser avec reverse() vous pouvez le faire : request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))

3 votes

Merci pour cette réponse utile. Rien de mieux que le code lui-même. (Par ailleurs, vous vouliez probablement dire url_name au lieu de view_name )

3 votes

@Anupam reverse() est défini comme suit : def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)

0 votes

@ébewè comment l'utiliser dans un modèle ?

72voto

shacker Points 3348

Si vous ne pouvez pas accéder à request alors vous ne pouvez pas utiliser get_current_site(request) comme le recommandent certaines solutions ici. Vous pouvez utiliser une combinaison du cadre natif de Sites et de get_absolute_url au lieu de cela. Mettez en place au moins un Site dans l'admin, assurez-vous que votre modèle possède un get_absolute_url() alors :

>>> 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 = f'https://{domain}{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

8 votes

C'est très pratique lorsque vous n'avez pas accès à l'objet HttpRequest, par exemple dans les tâches, les signaux, etc.

6 votes

Avant d'utiliser cette fonction, vous devez activer le cadre des sites docs.djangoproject.com/fr/dev/ref/contrib/sites/

0 votes

Pour remplacer example.com par quelque chose d'autre : Site.objects.all()[0] renvoie 'example.com' et a id=1, ce qui est spécifié dans settings.py. Il suffit de faire Site.objects.create(name='production', domain='prodsite.com') et de mettre SITE_ID=2 dans settings.py. Maintenant, Site.objects.get_current().domain renvoie 'prodsite.com'.

67voto

Darb Points 591

Vous pouvez également utiliser get_current_site dans le cadre de l'application sites ( from django.contrib.sites.models import get_current_site ). Il prend un objet de requête et utilise par défaut l'objet de site que vous avez configuré à l'aide de la commande SITE_ID dans settings.py si la requête est None . Plus d'informations dans la documentation pour utiliser le cadre des sites

par exemple

from django.contrib.sites.shortcuts import get_current_site
request = None
full_url = ''.join(['http://', get_current_site(request).domain, obj.get_absolute_url()])

Il n'est pas aussi compact/naturel que le request.build_absolute_url() mais il est utilisable lorsque les objets de requête ne sont pas disponibles et que vous disposez d'une URL de site par défaut.

6 votes

Je crois que ma question précisait "sans le module Sites". Est-ce que cela touche la base de données ?

3 votes

Le module Sites a été écrit pour mettre en cache les objets Site en utilisant la mise en cache au niveau du module (c'est-à-dire que vous n'avez pas besoin du cadre de mise en cache), de sorte que la base de données ne devrait être touchée que la première fois qu'un Site est récupéré par un processus web. Si vous n'avez pas django.contrib.sites dans votre INSTALLED_APPS il ne consultera pas du tout la base de données et fournira des informations basées sur l'objet Request (voir get_current_site )

1 votes

Dans ce cas, vous pouvez obtenir un +1, mais build_absolute_uri semble toujours être la solution la plus simple et la plus propre.

11voto

Kugel Points 4595

Examiner Request.META dictionnaire qui entre en jeu. Je pense qu'il contient le nom et le port du serveur.

3 votes

Use request.META['HTTP_HOST']

4 votes

L'objet de la demande comporte un hôte. N'examinez pas les méta directement : docs.djangoproject.com/fr/1.8/ref/request-response/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X