मुझे Django टेम्पलेट के भीतर से अपनी वर्तमान साइट का डोमेन नाम कैसे मिलेगा? मैंने टैग और फ़िल्टर में देखने की कोशिश की है, लेकिन वहां कुछ भी नहीं है।
मुझे Django टेम्पलेट के भीतर से अपनी वर्तमान साइट का डोमेन नाम कैसे मिलेगा? मैंने टैग और फ़िल्टर में देखने की कोशिश की है, लेकिन वहां कुछ भी नहीं है।
जवाबों:
मुझे लगता है कि आप जो चाहते हैं वह अनुरोध संदर्भ के लिए उपयोग करना है, RequestContext देखें।
Host:
हेडर को खराब कर देता है और किसी पृष्ठ पर स्पूफ किए गए डोमेन के साथ प्रतिक्रिया प्राप्त करता है, तो वह सुरक्षा छेद कैसे बनाता है? मैं यह नहीं देखता कि जेनरेट किए गए HTML को लेने वाले उपयोगकर्ता से कैसे भिन्न होता है और इसे अपने ब्राउज़र में फीड करने से पहले खुद को संशोधित करता है।
यदि आप वास्तविक HTTP होस्ट हेडर चाहते हैं, तो @ Phsiao के उत्तर पर डैनियल रोजमैन की टिप्पणी देखें। दूसरा विकल्प अगर आप कंट्रिब.साइट्स फ्रेमवर्क का उपयोग कर रहे हैं , तो आप डेटाबेस में किसी साइट के लिए एक कैनोनिकल डोमेन नाम सेट कर सकते हैं (अनुरोध डोमेन को उचित SITE_ID के साथ सेटिंग फ़ाइल में मैप करना कुछ ऐसा है जिसे आपको अपने आप से करना होगा वेबसर्वर सेटअप)। उस मामले में आप देख रहे हैं:
from django.contrib.sites.models import Site
current_site = Site.objects.get_current()
current_site.domain
यदि आप इसका उपयोग करना चाहते हैं, तो आपको करंट संदर्भ में current_site ऑब्जेक्ट को स्वयं डालना होगा। यदि आप इसे पूरे स्थान पर उपयोग कर रहे हैं, तो आप एक टेम्पलेट संदर्भ प्रोसेसर में पैकेज कर सकते हैं।
SITE_ID
सेटिंग id
साइट एप्लिकेशन की वर्तमान साइट की विशेषता के बराबर है (आप id
साइट व्यवस्थापक पैनल में पा सकते हैं )। जब आप कॉल करते हैं get_current
, तो Django आपका लेता है SITE_ID
और Site
डेटाबेस से उस आईडी के साथ ऑब्जेक्ट लौटाता है ।
print("get_current_site: ", get_current_site(request)) print("absolute uri: ", request.build_absolute_uri()) print("HTTP_HOST: ", request.META['HTTP_HOST']) get_current_site: localhost:8001 absolute uri: http://localhost:8001/... HTTP_HOST: localhost:8001
मैंने {{ request.get_host }}
विधि खोज ली है।
HTTP_X_FORWARDED_HOST
HTTP हेडर के खाते में ले जाता है ।
request.build_absolute_uri
( docs.djangoproject.com/en/dev/ref/request-response/… )
कार्ल मेयर को लागू करते हुए, आप इस तरह एक संदर्भ प्रोसेसर बना सकते हैं:
from django.conf import settings
def site(request):
return {'SITE_URL': settings.SITE_URL}
SITE_URL = 'http://google.com' # this will reduce the Sites framework db call.
TEMPLATE_CONTEXT_PROCESSORS = (
...
"module.context_processors.site",
....
)
यदि आप संदर्भ प्रोसेसर में सबडोमेन या एसएसएल को हैंडल करना चाहते हैं, तो अपनी खुद की रूटीन लिख सकते हैं।
मेरे द्वारा उपयोग किए जाने वाले संदर्भ प्रोसेसर की भिन्नता है:
from django.contrib.sites.shortcuts import get_current_site
from django.utils.functional import SimpleLazyObject
def site(request):
return {
'site': SimpleLazyObject(lambda: get_current_site(request)),
}
SimpleLazyObject
आवरण यकीन है कि डीबी कॉल केवल तब होता है जब टेम्पलेट वास्तव में उपयोग करता है बनाता है site
वस्तु। यह व्यवस्थापक पृष्ठों से क्वेरी हटाता है। यह परिणाम भी कैश करता है।
और इसे सेटिंग्स में शामिल करें:
TEMPLATE_CONTEXT_PROCESSORS = (
...
"module.context_processors.site",
....
)
टेम्पलेट में, आप {{ site.domain }}
वर्तमान डोमेन नाम प्राप्त करने के लिए उपयोग कर सकते हैं ।
संपादित करें: प्रोटोकॉल स्विचिंग का भी समर्थन करें , उपयोग करें:
def site(request):
site = SimpleLazyObject(lambda: get_current_site(request))
protocol = 'https' if request.is_secure() else 'http'
return {
'site': site,
'site_root': SimpleLazyObject(lambda: "{0}://{1}".format(protocol, site.domain)),
}
SimpleLazyObject
यहां उपयोग करने की आवश्यकता नहीं है, क्योंकि लैंबडा अभ्यस्त होने पर भी कुछ भी नहीं कहा जा सकता है।
SimpleLazyObject
, तो प्रत्येक RequestContext
कॉल करेगा get_current_site()
, और इसलिए SQL क्वेरी निष्पादित करेगा । आवरण सुनिश्चित करता है कि चर का मूल्यांकन केवल तब किया जाता है जब वह वास्तव में टेम्पलेट में उपयोग किया जाता है।
SimpleLazyObject
समारोह, जो वास्तव में जरूरत नहीं है के बाद से की पुनर्मूल्यांकन से बचने के लिए है Site
वस्तु कैश किया गया है।
from django.contrib.sites.shortcuts import get_current_site
मुझे पता है कि यह सवाल पुराना है, लेकिन मैंने इसे मौजूदा डोमेन प्राप्त करने के लिए एक पैथोनिक तरीके की तलाश में ठोकर खाई।
def myview(request):
domain = request.build_absolute_uri('/')[:-1]
# that will build the complete domain: http://foobar.com
त्वरित और सरल, लेकिन उत्पादन के लिए अच्छा नहीं:
(एक दृश्य में)
request.scheme # http or https
request.META['HTTP_HOST'] # example.com
request.path # /some/content/1/
(एक टेम्पलेट में)
{{ request.scheme }} :// {{ request.META.HTTP_HOST }} {{ request.path }}
यदि आप रेंडर का उपयोग कर रहे हैं, तो एक RequestContext का उपयोग करना सुनिश्चित करें ।
request.META['HTTP_HOST']
उत्पादन पर भरोसा न करें : यह जानकारी ब्राउज़र से आती है। इसके बजाय, @ कार्लमेयर के उत्तर का उपयोग करें
request.scheme
। शायद केवल django के नए संस्करणों में उपलब्ध है।
request.scheme
को Django 1.7 में जोड़ा गया था।
{{ request.get_host }}
जब ALLOWED_HOSTS
सेटिंग (Django 1.4.4 में जोड़ा) के साथ प्रयोग किया जाता है HTTP होस्ट हेडर हमलों के खिलाफ की रक्षा करनी चाहिए ।
ध्यान दें कि {{ request.META.HTTP_HOST }}
समान सुरक्षा नहीं है। डॉक्स देखें :
ALLOWED_HOSTS
होस्ट / डोमेन नामों का प्रतिनिधित्व करने वाले स्ट्रिंग्स की एक सूची जो इस Django साइट की सेवा कर सकती है। यह HTTP होस्ट हेडर हमलों को रोकने के लिए एक सुरक्षा उपाय है , जो कई प्रतीत होने वाले सुरक्षित वेब सर्वर कॉन्फ़िगरेशन के तहत भी संभव है।
... यदि
Host
शीर्ष लेख (याX-Forwarded-Host
यदिUSE_X_FORWARDED_HOST
सक्षम है) इस सूची में किसी भी मूल्य से मेल नहीं खाता है, तोdjango.http.HttpRequest.get_host()
विधि बढ़ेगीSuspiciousOperation
।... यह मान्यता केवल के माध्यम से लागू होती है
get_host()
; यदि आपका कोड होस्ट हैडर से सीधेrequest.META
आप तक पहुँचता है, तो आप इस सुरक्षा सुरक्षा को दरकिनार कर रहे हैं।
request
अपने टेम्प्लेट में उपयोग करने के लिए , Django 1.8 में टेम्प्लेट-रेंडरिंग फ़ंक्शन कॉल बदल गए हैं , इसलिए आपको अब RequestContext
सीधे हैंडल नहीं करना है ।
शॉर्टकट फ़ंक्शन का उपयोग करके किसी टेम्पलेट को देखने के लिए कैसे प्रस्तुत किया जाए render()
:
from django.shortcuts import render
def my_view(request):
...
return render(request, 'my_template.html', context)
ईमेल के लिए एक टेम्प्लेट प्रस्तुत करने का तरीका यहां बताया गया है, जो IMO अधिक सामान्य मामला है जहां आप होस्ट मान चाहते हैं:
from django.template.loader import render_to_string
def my_view(request):
...
email_body = render_to_string(
'my_template.txt', context, request=request)
यहां ईमेल टेम्प्लेट में एक पूर्ण URL जोड़ने का एक उदाहरण है; request.scheme मिलना चाहिए http
या https
जो आप उपयोग कर रहे हैं उसके आधार पर:
Thanks for registering! Here's your activation link:
{{ request.scheme }}://{{ request.get_host }}{% url 'registration_activate' activation_key %}
मैं एक कस्टम टेम्पलेट टैग का उपयोग करता हूं। उदाहरण के लिए <your_app>/templatetags/site.py
:
# -*- coding: utf-8 -*-
from django import template
from django.contrib.sites.models import Site
register = template.Library()
@register.simple_tag
def current_domain():
return 'http://%s' % Site.objects.get_current().domain
इस तरह की एक टेम्प्लेट में उपयोग करें:
{% load site %}
{% current_domain %}
get_current
एक प्रलेखित विधि है: docs.djangoproject.com/en/dev/ref/contrib/sites/…
'http://%s'
https
कनेक्शन के मामले में समस्या हो सकती है ; इस मामले में योजना गतिशील नहीं है।
उपयोगकर्ता के पंचकोश के उत्तर के समान, यह वही है जो मैंने एक बहुत ही सरल वेबसाइट पर किया था। यह कुछ चर प्रदान करता है और उन्हें टेम्पलेट पर उपलब्ध कराता है।
SITE_URL
की तरह एक मूल्य पकड़ होगा example.com
SITE_PROTOCOL
की तरह एक मूल्य पकड़ होगा http
या https
SITE_PROTOCOL_URL
की तरह एक मूल्य पकड़ होगा http://example.com
या https://example.com
SITE_PROTOCOL_RELATIVE_URL
की तरह एक मूल्य पकड़ होगा //example.com
।
मॉड्यूल / context_processors.py
from django.conf import settings
def site(request):
SITE_PROTOCOL_RELATIVE_URL = '//' + settings.SITE_URL
SITE_PROTOCOL = 'http'
if request.is_secure():
SITE_PROTOCOL = 'https'
SITE_PROTOCOL_URL = SITE_PROTOCOL + '://' + settings.SITE_URL
return {
'SITE_URL': settings.SITE_URL,
'SITE_PROTOCOL': SITE_PROTOCOL,
'SITE_PROTOCOL_URL': SITE_PROTOCOL_URL,
'SITE_PROTOCOL_RELATIVE_URL': SITE_PROTOCOL_RELATIVE_URL
}
settings.py
TEMPLATE_CONTEXT_PROCESSORS = (
...
"module.context_processors.site",
....
)
SITE_URL = 'example.com'
फिर, अपने टेम्पलेट्स पर, उन्हें के रूप में उपयोग {{ SITE_URL }}
, {{ SITE_PROTOCOL }}
, {{ SITE_PROTOCOL_URL }}
और{{ SITE_PROTOCOL_RELATIVE_URL }}
एक Django टेम्पलेट में आप कर सकते हैं:
<a href="{{ request.scheme }}://{{ request.META.HTTP_HOST }}{{ request.path }}?{{ request.GET.urlencode }}" >link</a>
django.template.context_processors.request
[यह कैसे-करने में मदद मिली] (भी simpleisbetterthancomplex.com/tips/2016/07/20/... )
यदि आप "अनुरोध" संदर्भ प्रोसेसर का उपयोग करते हैं, और Django साइटों के ढांचे का उपयोग कर रहे हैं , और साइट मिडलवेयर स्थापित है (यानी आपकी सेटिंग्स शामिल हैं):
INSTALLED_APPS = [
...
"django.contrib.sites",
...
]
MIDDLEWARE = [
...
"django.contrib.sites.middleware.CurrentSiteMiddleware",
...
]
TEMPLATES = [
{
...
"OPTIONS": {
"context_processors": [
...
"django.template.context_processors.request",
...
]
}
}
]
... तो आपके पास request
टेम्पलेट में उपलब्ध वस्तु होगी , और इसमें Site
अनुरोध के रूप में वर्तमान का संदर्भ होगा request.site
। फिर आप इसके साथ एक टेम्पलेट में डोमेन पुनः प्राप्त कर सकते हैं:
{{request.site.domain}}
इस दृष्टिकोण के बारे में क्या? मेरे लिये कार्य करता है। इसका उपयोग django-Registration में भी किया जाता है ।
def get_request_root_url(self):
scheme = 'https' if self.request.is_secure() else 'http'
site = get_current_site(self.request)
return '%s://%s' % (scheme, site)
localhost
करने पर आपको एक https
स्कीम मिल जाएगी (इसे सुरक्षित माना जाता है) जो तब काम नहीं करेगी जब आपको स्टैटिक यूआरएल मिल गया हो (केवल http://127.0.0.1
मान्य है, नहीं https://127.0.0.1
)। तो यह आदर्श नहीं है जब अभी भी विकास में है।
from django.contrib.sites.models import Site
if Site._meta.installed:
site = Site.objects.get_current()
else:
site = RequestSite(request)
आप {{ protocol }}://{{ domain }}
अपने डोमेन नाम प्राप्त करने के लिए अपने टेम्पलेट में उपयोग कर सकते हैं ।
request.META['HTTP_HOST']
आपको डोमेन देता है। एक टेम्पलेट में यह होगा{{ request.META.HTTP_HOST }}
।