Djangoテンプレート内から現在のサイトのドメイン名を取得するにはどうすればよいですか?タグとフィルターを調べてみましたが、何もありませんでした。
あなたが望むのは、リクエストコンテキストにアクセスできることだと思います。RequestContextを参照してください。
実際のHTTP Hostヘッダーが必要な場合は、@ Phsiaoの回答に関するDaniel Rosemanのコメントを参照してください。他の選択肢は、 contrib.sites framework を使用している場合、データベース内のサイトに正規のドメイン名を設定できます(適切なSITE_IDを持つ設定ファイルに要求ドメインをマッピングすることです)ウェブサーバーの設定で自分で行う必要があります)。その場合、あなたは探しています:
from Django.contrib.sites.models import Site
current_site = Site.objects.get_current()
current_site.domain
current_siteオブジェクトを使用する場合は、自分でテンプレートコンテキストに入れる必要があります。あらゆる場所で使用している場合は、テンプレートコンテキストプロセッサにパッケージ化できます。
{{ request.get_Host }}
メソッドを発見しました。
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
ラッパーは、テンプレートが実際にsite
オブジェクトを使用する場合にのみDB呼び出しが行われるようにします。これにより、管理ページからクエリが削除されます。結果もキャッシュします。
それを設定に含めます:
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)),
}
私はこの質問が古いことを知っていますが、現在のドメインを取得するための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 }}
必ず RequestContext を使用してください。これは render を使用している場合に当てはまります。
本番環境でrequest.META['HTTP_Host']
を信頼しないでください。その情報はブラウザから取得されます。代わりに、@ CarlMeyerの答えを使用してください
{{ request.get_Host }}
をALLOWED_HOSTS
設定(Django 1.4.4で追加)と組み合わせて使用すると、HTTPホストヘッダー攻撃から保護する必要があります。
{{ request.META.HTTP_Host }}
には同じ保護機能がないことに注意してください。 docs を参照してください:
ALLOWED_HOSTS
このDjangoサイトが提供できるホスト/ドメイン名を表す文字列のリスト。これは HTTPホストヘッダー攻撃 を防ぐためのセキュリティ対策です。
...
Host
ヘッダー(またはX-Forwarded-Host
が有効になっている場合はUSE_X_FORWARDED_Host
)がこのリストのどの値とも一致しない場合、Django.http.HttpRequest.get_Host()
メソッドはSuspiciousOperation
を発生させます。 。...この検証は、
get_Host()
を介してのみ適用されます。コードがrequest.META
から直接Hostヘッダーにアクセスする場合、このセキュリティ保護をバイパスしています。
テンプレートでrequest
を使用する場合、テンプレートレンダリング関数の呼び出しには Django 1.8で変更 があるため、RequestContext
を処理する必要はありません。直接。
ショートカット関数render()
を使用して、ビューのテンプレートをレンダリングする方法は次のとおりです。
from Django.shortcuts import render
def my_view(request):
...
return render(request, 'my_template.html', context)
メールのテンプレートをレンダリングする方法は次のとおりです。IMOは、Host値が必要な場合のより一般的なケースです。
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 %}
ユーザー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>
from Django.contrib.sites.models import Site
if Site._meta.installed:
site = Site.objects.get_current()
else:
site = RequestSite(request)
このアプローチはどうですか?私のために働く。 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)