मुझे Django में पूर्ण / पूर्ण URL (डोमेन के साथ) कैसे मिल सकता है?


379

मैं साइट मॉड्यूल के बिनाhttps://example.com/some/path Django में पूर्ण / पूर्ण URL (जैसे ) कैसे प्राप्त कर सकता हूं ? यह सिर्फ मूर्खतापूर्ण है ... मुझे URL को रोके रखने के लिए अपने DB को क्वेरी करने की आवश्यकता नहीं है!

मैं इसके साथ उपयोग करना चाहता हूं reverse()


11
एक तरफ के रूप में: साइट मॉड्यूल केवल DB को पहली बार हिट करता है जब उसे साइट के नाम की आवश्यकता होती है, परिणाम एक मॉड्यूल चर (SITE_CACHE) में कैश्ड होता है जो मॉड्यूल या SiteManager .clear_cache () के पुन: संकलन तक चारों ओर चिपक जाएगा विधि कहा जाता है। देखें: code.djangoproject.com/svn/django/tags/releases/1.3/django/…
कर्नल स्पोंसज़

जवाबों:


512

उपयोगी अनुरोध का उपयोग करें। अनुरोध पर_बसूल_बुरी () विधि, इसे रिश्तेदार url पास करें और यह आपको पूर्ण प्रदान करेगा।

डिफ़ॉल्ट रूप से, के लिए पूर्ण URL request.get_full_path()वापस आ गया है, लेकिन आप इसे किसी निरपेक्ष URL में बदलने के लिए पहले तर्क के रूप में एक सापेक्ष URL पास कर सकते हैं।


3
Url के बारे में क्या: लोकलहोस्ट / होम / # / टेस्ट ? मैं केवल लोकलहोस्ट / होम देख सकता हूं । मैं तेज के बाद भाग कैसे देख सकता हूं ?
सेगज़ैच

41
# के बाद सब कुछ सर्वर से पारित नहीं होता है, यह केवल ब्राउज़र की सुविधा है
दिमित्री

69
एक टेम्पलेट में (जहां आप पैरामीटर नहीं दे सकते हैं) आप बस ऐसा कर सकते हैं: {{ request.build_absolute_uri }}{{ object.get_absolute_url }}- और हायो, पूर्ण यूआरएल।
ओडिन्हो - वेलमॉन्ट

17
और क्या होगा अगर मेरे पास अनुरोध तक पहुंच नहीं है? जैसे Django-REST- फ्रेमवर्क के सीरियल में?
दिमाग

15
मुझे उपयोग {% if request.is_secure %}https://{% else %}http://{% endif %}{{ request.get_host }}{{ object.get_absolute_url }}करना {{ request.build_absolute_uri }}पड़ा क्योंकि एक अनुगामी स्लैश था और स्लैश के {{ object.get_absolute_url }}साथ शुरू हुआ जिसके परिणामस्वरूप URL में डबल स्लैश हो गया।
xtranophilist

96

यदि आप इसका उपयोग करना चाहते reverse()हैं तो आप ऐसा कर सकते हैं:request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))


3
उपयोगी उत्तर के लिए धन्यवाद। कोड से बेहतर कुछ भी नहीं। (यह भी, आप शायद के url_nameबजाय इसका मतलब था view_name)
अनुपम

3
@ अनुपम रिवर्स () के रूप में परिभाषित किया गया है:def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)
माटीस एल्गार्ट

57

आप get_current_siteसाइट्स ऐप ( from django.contrib.sites.models import get_current_site) के हिस्से के रूप में भी उपयोग कर सकते हैं । यह अनुरोध ऑब्जेक्ट लेता है, और SITE_IDयदि अनुरोध है, तो साइट सेटिंग्स में आपके द्वारा कॉन्फ़िगर की गई साइट ऑब्जेक्ट के लिए डिफ़ॉल्ट हैNoneसाइटों के ढांचे का उपयोग करने के लिए प्रलेखन में और अधिक पढ़ें

जैसे

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

यह उतना कॉम्पैक्ट / साफ-सुथरा नहीं है request.build_absolute_url(), लेकिन जब वस्तुएं उपलब्ध नहीं होती हैं तो यह प्रयोग करने योग्य होता है, और आपके पास एक डिफ़ॉल्ट साइट यूआरएल होती है।


4
मेरा मानना ​​है कि मेरा प्रश्न विशेष रूप से "साइट मॉड्यूल के बिना" कहा गया है। क्या यह डीबी को हिट करता है?
मप्र

1
साइट मॉड्यूल को मॉड्यूल स्तर कैशिंग (यानी आपको कैश फ्रेमवर्क की आवश्यकता नहीं है) का उपयोग करते हुए साइट ऑब्जेक्ट को कैश करने के लिए लिखा गया है, इसलिए डीबी को केवल पहली बार हिट करना चाहिए जब साइट किसी वेब प्रक्रिया द्वारा पुनर्प्राप्त की जाती है। आप नहीं है, तो django.contrib.sitesअपने में INSTALLED_APPS, यह सब पर डीबी मारा नहीं होगा, और अनुरोध वस्तु के आधार पर जानकारी प्रदान करते हैं (देखें get_current_site )
Darb

1
वैसे तो आपके पास एक +1 हो सकता है, लेकिन फिर build_absolute_uriभी यह आसान और क्लीनर समाधान की तरह दिखता है।
एमपीएन

1
यदि आप ईमेल भेजने के लिए संकेतों में URL जनरेट करने का प्रयास कर रहे हैं तो यह एक सटीक उत्तर है।
क्रिस

2
काम नहीं करता है, अगर आप https का उपयोग करते हैं। हाँ, आप s जोड़ सकते हैं, लेकिन क्या आप https स्थानीय रूप से विकसित करते हैं? और क्या आपको हमेशा पता है, अगर आपके पास https है लेकिन कभी-कभी नहीं ...?
tjati 12

55

यदि आप requestतब तक पहुँच नहीं पाते हैं, तो आप get_current_site(request)यहाँ कुछ समाधानों में अनुशंसित उपयोग नहीं कर सकते हैं। आप नेटिव साइट्स फ्रेमवर्क के संयोजन का उपयोग कर सकते हैं और get_absolute_urlइसके बजाय। व्यवस्थापक में कम से कम एक साइट सेट करें , सुनिश्चित करें कि आपके मॉडल में एक get_absolute_url () विधि है, फिर:

>>> 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


7
यह वास्तव में आसान है जब आपके पास HttpRequest ऑब्जेक्ट तक पहुंच नहीं है। जैसे कार्यों, संकेतों आदि में
अरशम

6
इसका उपयोग करने से पहले आपको साइटों के ढांचे को सक्षम करना चाहिए docs.djangoproject.com/en/dev/ref/contrib/sites/…
madzohan

Example.com को किसी चीज़ में बदलने के लिए: Site.objects.all () [0] 'example.com' लौटाता है और इसमें id = 1 होता है, जो settings.py में निर्दिष्ट होता है। बस Site.objects.create (नाम = 'उत्पादन', डोमेन = 'prodsite.com') करें और सेटिंग में SITE_ID = 2 सेट करें। अब Site.objects.get_current ()। डोमेन 'prodsite.com' लौटाता है।
गीक

आप सेट कर सकते हैं requestकरने के लिए Noneया कॉल get_current_site(None)
बोबार्ट

20

यदि आप डेटाबेस को हिट नहीं करना चाहते हैं, तो आप इसे एक सेटिंग के साथ कर सकते हैं। फिर, इसे हर टेम्पलेट में जोड़ने के लिए एक संदर्भ प्रोसेसर का उपयोग करें:

# 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>

17

आपके विचार में, बस यह करें:

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

14

django-fullurl

यदि आप एक Django टेम्पलेट में यह करने के लिए प्रयास कर रहे हैं, मैं एक छोटे से PyPI पैकेज जारी किया है django-fullurlआप की जगह जाने के लिए urlऔर staticके साथ टेम्पलेट टैग fullurlऔर fullstatic, इस तरह:

{% load fullurl %}

Absolute URL is: {% fullurl "foo:bar" %}

Another absolute URL is: {% fullstatic "kitten.jpg" %}

इन बैज को उम्मीद के साथ स्वचालित रूप से अद्यतन रहना चाहिए:

PyPI ट्रैविस सीआई

एक दृश्य में, आप request.build_absolute_uriइसके बजाय निश्चित रूप से उपयोग कर सकते हैं ।


शर्म करो यह 2.0 के साथ काम नहीं करता है। एक पीआर पुश अप करने की आवश्यकता हो सकती है।
स्टीवन चर्च

@StevenChurch यह काम करना चाहिए। मैंने Django 2.0 को अभी तक समर्थित के रूप में चिह्नित नहीं किया है, लेकिन मौजूदा संस्करण को काम करना चाहिए।
फ़्लिम

अपनी आवश्यकताओं के लिए मैंने फेलबैक के लिए हरोकू से एक ईएनवी पास करके इसे राउंड किया। मेरा मुद्दा ईमेल टेम्प्लेट से गुजरने के लिए URL प्राप्त कर रहा है। मैं समस्या को याद नहीं कर सकता, लेकिन यह एक Django परिवर्तन के कारण काम नहीं किया।
स्टीवन चर्च

@StevenChurch मुझे लगता है कि ईमेल बनाते समय मुद्दा यह है कि requestडोमेन नाम प्राप्त करने के लिए कोई ऑब्जेक्ट नहीं है। उस स्थिति में, आपको sitesइसके बजाय फ्रेमवर्क का उपयोग करना चाहिए , जो डेटाबेस से डोमेन नाम प्राप्त करता है। देखें django-absoluteuri, इस PyPI पैकेज के README के ​​"देखें" अनुभाग में उल्लेख किया गया है।
फ्लिम्स

8

टेम्प्लेट से किसी अन्य पेज का पूरा लिंक बनाने के लिए, आप इसका उपयोग कर सकते हैं:

{{ request.META.HTTP_HOST }}{% url 'views.my_view' my_arg %}

request.META.HTTP_HOST होस्ट नाम देता है, और url संबंधित नाम देता है। टेम्प्लेट इंजन फिर उन्हें एक पूर्ण url में बदल देता है।


2
उत्तर प्रोटोकॉल ( httpइस संदर्भ में) और ://URL के भाग को याद कर रहा है , इसलिए यह पूर्ण url प्रदान नहीं करेगा ।
user272735

2
अनुरोध ऑब्जेक्ट पर एक होस्ट है। सीधे मेटा की जाँच न करें: docs.djangoproject.com/en/1.8/ref/request-response/…
किट

8

फिर भी एक और तरीका। आप build_absolute_uri()अपने में उपयोग कर सकते हैं view.pyऔर इसे टेम्पलेट में पास कर सकते हैं ।

view.py

def index(request):
    baseurl = request.build_absolute_uri()
    return render_to_response('your-template.html', { 'baseurl': baseurl })

अपने-template.html

{{ baseurl }}

HttpRequest.build_absolute_uri(request)यह नहीं के बराबर है request.build_absolute_uri()?
एमपीएन

7

Request.METAशब्दकोश का परीक्षण करें जो अंदर आता है। मुझे लगता है कि इसमें सर्वर नाम और सर्वर पोर्ट है।


2
अनुरोध का उपयोग करें। एमईटीए ['HTTP_HOST']
एंटनी

4
अनुरोध ऑब्जेक्ट पर एक होस्ट है। सीधे मेटा की जाँच न करें: docs.djangoproject.com/en/1.8/ref/request-response/…
किट

7

निम्नलिखित कोड का प्रयास करें:

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

वह सिर्फ पथ और क्वेरी स्ट्रिंग के बिना डोमेन देगा, नहीं?
मप्र

6

इसने मेरे खाके में काम किया:

{{ request.scheme }}:{{ request.META.HTTP_HOST }}{% url  'equipos:marca_filter' %}

मुझे js लाने के लिए इसे फुल url चाहिए। उम्मीद है इससे आपको मदद होगी।


5

मैं जानता हूं कि यह एक पुराना सवाल है। लेकिन मुझे लगता है कि लोग अभी भी इसमें बहुत भागते हैं।

वहाँ पुस्तकालयों की एक जोड़ी है कि डिफ़ॉल्ट Django कार्यक्षमता के पूरक हैं। मैंने कुछ कोशिश की है। मुझे निम्न पुस्तकालय पसंद है जब उल्टा पूर्ण यूआरएल संदर्भित करता है:

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

एक और एक मुझे पसंद है क्योंकि आप आसानी से एक डोमेन, प्रोटोकॉल और पथ को एक साथ रख सकते हैं:

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

यह लाइब्रेरी आपको अपने टेम्पलेट में बस वही लिखने की अनुमति देती है, जो आप चाहते हैं:

{{url_parts.domain}}

4

यदि आप django REST फ्रेमवर्क का उपयोग कर रहे हैं, तो आप रिवर्स फ़ंक्शन का उपयोग कर सकते हैं rest_framework.reverse। इसके समान व्यवहार है django.core.urlresolvers.reverse, सिवाय इसके कि यह एक पूर्ण 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,))

केवल REST फ्रेमवर्क में उपलब्धता का उल्लेख करने के लिए संपादित


मुझे उपयोग करने में त्रुटि हुई request=request। यह भी ऐसा प्रतीत नहीं होता है कि अनुरोध यहाँ दस्तावेज़ित है। docs.djangoproject.com/en/1.9/ref/urlresolvers/#reverse
रयान अमोस

यदि आप REST फ्रेमवर्क का उपयोग कर रहे हैं तो मैं इसका उल्लेख करना भूल गया। अच्छी पकड़, मैंने अपना जवाब अपडेट कर दिया है।
जॉनजी

हां धन्यवाद - यह django REST फ्रेमवर्क के
Apurv Kansal

1

मैं समझ गया:

wsgiref.util.request_uri(request.META)

स्कीमा, होस्ट, पोर्ट पथ और क्वेरी के साथ पूर्ण uri प्राप्त करें।


0

एक सेटिंग के रूप में उपलब्ध ABSOLUTE_URL_OVERRIDES भी है

https://docs.djangoproject.com/en/2.1/ref/settings/#absolute-url-overrides

लेकिन यह ओवरराइड get_absolute_url (), जो वांछनीय नहीं हो सकता है।

इसके लिए केवल साइट फ्रेमवर्क स्थापित करने या यहां बताए गए कुछ अन्य सामानों को करने के बजाय, जो अनुरोध ऑब्जेक्ट पर निर्भर करता है, मुझे लगता है कि इसका बेहतर समाधान मॉडल थ्रेड में रखना है।

BASE_URL को settings.py में परिभाषित करें, फिर इसे model.py में आयात करें और एक अमूर्त वर्ग बनाएं (या इसे आप पहले से उपयोग कर रहे हैं में जोड़ें) जो get_truly_absolute_url () को परिभाषित करता है। यह उतना ही सरल हो सकता है:

def get_truly_absolute_url(self):
    return BASE_URL + self.get_absolute_url()

इसे Subclass करें और अब आप इसे हर जगह उपयोग कर सकते हैं।


0

जैसा कि अन्य उत्तरों में उल्लेख किया गया है, request.build_absolute_uri()यदि आप तक पहुँच है request, औरsites जब तक विभिन्न URL अलग-अलग डेटाबेस की ओर इंगित करते हैं, तब तक फ्रेमवर्क बढ़िया है।

हालाँकि, मेरा उपयोग का मामला थोड़ा अलग था। मेरा स्टेजिंग सर्वर और प्रोडक्शन सर्वर एक ही डेटाबेस को एक्सेस करते हैं, लेकिन get_current_siteदोनों ने siteडेटाबेस में पहला लौटाया । इसे हल करने के लिए, आपको किसी प्रकार के पर्यावरण चर का उपयोग करना होगा। आप अलग-अलग सर्वर और अलग-अलग सेटिंग्स के लिए 1) एक पर्यावरण चर (कुछ ऐसा os.environ.get('SITE_URL', 'localhost:8000')) या 2) का उपयोग कर सकते हैंSITE_ID

उम्मीद है कि किसी को यह उपयोगी मिलेगा!


0

मैं इस सूत्र में आया था क्योंकि मैं एक सफल पृष्ठ के लिए एक पूर्ण यूआरआई का निर्माण करना चाह रहा था। request.build_absolute_uri()मुझे अपने वर्तमान दृश्य के लिए एक URI दिया, लेकिन अपने सफलता दृश्य के लिए URI प्राप्त करने के लिए मैंने निम्नलिखित का उपयोग किया ...।

request.build_absolute_uri (रिवर्स ( 'success_view_name'))


-2

request.get_host() आपको डोमेन देगा।


1
प्रश्न में कहा गया है, पूर्ण URL
acidjunk

-5

आप भी उपयोग कर सकते हैं:

import socket
socket.gethostname()

यह मेरे लिए ठीक काम कर रहा है,

मुझे पूरा यकीन नहीं है कि यह कैसे काम करता है। मेरा मानना ​​है कि यह थोड़ा और निम्न स्तर है और आपके सर्वर को होस्टनाम लौटाएगा, जो आपके पेज पर पहुंचने के लिए आपके उपयोगकर्ता द्वारा उपयोग किए जाने वाले होस्टनाम से भिन्न हो सकता है।


हाँ..आपने समस्या बताई। होस्टनाम आवश्यक रूप से डोमेन नाम के समान नहीं है।
5

यह एक बहुत अलग समस्या हल करती है। कई वेबसाइटों के साथ एक साझा होस्टिंग सर्वर पर विचार करें - ऊपर दिए गए कोड का उपयोग करके, URL उत्पन्न करने वाली सभी साइटों में होस्ट मशीन की ओर इशारा करते हुए ऐसे सभी URL होंगे, जो संभवतः किसी भी चलने वाली वेबसाइट नहीं है।
tbm

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.