मुझे 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_HOSTHTTP हेडर के खाते में ले जाता है ।
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 }}।