Djangoテンプレート内から現在のサイトのドメイン名を取得するにはどうすればよいですか?タグとフィルターを調べてみましたが、何もありません。
Djangoテンプレート内から現在のサイトのドメイン名を取得するにはどうすればよいですか?タグとフィルターを調べてみましたが、何もありません。
回答:
私はあなたが望むのはリクエストコンテキストにアクセスできることだと思います。RequestContextを見てください。
Host:
ヘッダーをスプーフィングし、ページのどこかにスプーフィングされたドメインで応答を受け取った場合、どのようにしてセキュリティホールが発生しますか?ユーザーが生成されたHTMLを取得して自分のブラウザーにフィードする前に自分自身を変更することと、それがどのように異なるかはわかりません。
実際のHTTPホストヘッダーが必要な場合は、@ Phsiaoの回答に関するDaniel Rosemanのコメントを参照してください。もう1つの方法は、contrib.sitesフレームワークを使用している場合、データベースのサイトの正規ドメイン名を設定できます(リクエストドメインを適切な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はを受け取り、データベースからそのID 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ヘッダーを考慮に入れるため、HTTPプロキシまたはロードバランサーを介してホストに到達すると、より完全になることに注意してください。
request.build_absolute_uri
(docs.djangoproject.com/en/dev/ref/request-response/...)
Carl Meyerを補完して、次のようなコンテキストプロセッサを作成できます。
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",
....
)
コンテキストプロセッサでサブドメインまたはSSLを処理する場合は、独自のルーティンを作成できます。
私が使用するコンテキストプロセッサのバリエーションは次のとおりです。
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
ラッパーは、テンプレートが実際に使用する際にDBコールがのみ発生を確認します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
私はこの質問が古いことを知っていますが、現在のドメインを取得するpythonicの方法を探して偶然見つけました。
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 }}
renderを使用している場合は、必ずRequestContextを使用してください。
request.META['HTTP_HOST']
本番環境を信用しないでください。その情報はブラウザからのものです。代わりに、@ CarlMeyerの回答を使用してください
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ホストヘッダー攻撃を防ぐためのセキュリティ対策です。これは、多くの安全なWebサーバー構成でも可能です。
...
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)
EMOのテンプレートをレンダリングする方法は次のとおりです。この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
接続の場合は問題になる可能性があります。この場合、スキームは動的ではありません。
ユーザーpanchicoreの返信と同様に、これは私が非常に単純なWebサイトで行ったことです。いくつかの変数を提供し、それらをテンプレートで使用できるようにします。
SITE_URL
のような値を保持するような値example.com
SITE_PROTOCOL
を保持するhttp
かhttps
SITE_PROTOCOL_URL
、のような値を保持するhttp://example.com
かhttps://example.com
SITE_PROTOCOL_RELATIVE_URL
、のような値を保持するでしょう//example.com
。
module / 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
(これは安全と考えています)あなたは、静的なURLを持っている場合は動作しませんどのスキームを(のみhttp://127.0.0.1
、有効ではありませんhttps://127.0.0.1
)。したがって、まだ開発中の場合は理想的ではありません。
{{ protocol }}://{{ domain }}
テンプレートでを使用して、ドメイン名を取得できます。
request.META['HTTP_HOST']
ドメインを提供します。テンプレートではそうなります{{ request.META.HTTP_HOST }}
。