Sitesモジュールなしhttps://example.com/some/path
でDjango の完全/絶対URL(例:) を取得するにはどうすればよいですか?それはばかげているだけです... URLを取得するためにDBをクエリする必要はありません!
で使いたいreverse()
。
Sitesモジュールなしhttps://example.com/some/path
でDjango の完全/絶対URL(例:) を取得するにはどうすればよいですか?それはばかげているだけです... URLを取得するためにDBをクエリする必要はありません!
で使いたいreverse()
。
回答:
リクエストに応じて便利なrequest.build_absolute_uri()メソッドを使用し、それに相対URLを渡すと、完全なURLが得られます。
デフォルトではの絶対URL request.get_full_path()
が返されますが、相対URLを最初の引数として渡して絶対URLに変換できます。
{{ request.build_absolute_uri }}{{ object.get_absolute_url }}
-heyho、完全なURL。
{% if request.is_secure %}https://{% else %}http://{% endif %}{{ request.get_host }}{{ object.get_absolute_url }}
れ{{ request.build_absolute_uri }}
ていたため、使用する必要があり{{ object.get_absolute_url }}
ました。
あなたがそれを使いたいreverse()
なら、これを行うことができます:request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))
url_name
代わりにを意味していましたview_name
)
def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)
get_current_site
サイトアプリ(from django.contrib.sites.models import get_current_site
)の一部として使用することもできます。リクエストオブジェクトを受け取り、リクエストがの場合、デフォルトSITE_ID
でsettings.pyで設定したサイトオブジェクトになります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()
ではありませんが、リクエストオブジェクトが利用できず、デフォルトのサイトURLがある場合に使用できます。
django.contrib.sites
、あなたの中でINSTALLED_APPS
、それがすべてでDBをヒットしないだろう、と(参照Requestオブジェクトに基づいて情報を提供get_current_site)
build_absolute_uri
それでも簡単でクリーンな解決策のように見えます。
アクセスできないrequest
場合はget_current_site(request)
、こちらのソリューションで推奨されているとおりに使用できません。get_absolute_url
代わりに、ネイティブのSitesフレームワークを組み合わせて使用できます。管理者に少なくとも1つのサイトを設定し、モデルに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
request
にNone
またはコールget_current_site(None)
。
データベースにアクセスしたくない場合は、設定を使用して実行できます。次に、コンテキストプロセッサを使用してすべてのテンプレートに追加します。
# 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>
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" %}
これらのバッジは、うまくいけば自動的に最新の状態に保たれるはずです。
ビューでは、もちろんrequest.build_absolute_uri
代わりに使用できます。
request
、ドメイン名を取得するオブジェクトがないことだと思います。その場合は、sites
代わりにデータベースからドメイン名を取得するフレームワークを使用する必要があります。参照してください。django-absoluteuri
これは、PyPIパッケージのREADMEの「も参照」の項で述べたように、。
テンプレートから別のページへの完全なリンクを作成するには、これを使用できます。
{{ request.META.HTTP_HOST }}{% url 'views.my_view' my_arg %}
request.META.HTTP_HOSTはホスト名を提供し、urlは相対名を提供します。次に、テンプレートエンジンはそれらを連結して完全なURLにします。
http
このコンテキストでは)と://
URLの一部が欠落しているため、完全なURLは提供されません。
さらに別の方法。で使用build_absolute_uri()
してview.py
、テンプレートに渡すことができます。
view.py
def index(request):
baseurl = request.build_absolute_uri()
return render_to_response('your-template.html', { 'baseurl': baseurl })
your-template.html
{{ baseurl }}
HttpRequest.build_absolute_uri(request)
と同等request.build_absolute_uri()
ですよね?
入っRequest.META
てくる辞書を調べてください。サーバー名とサーバーポートがあると思います。
これは私のテンプレートで私のために働きました:
{{ request.scheme }}:{{ request.META.HTTP_HOST }}{% url 'equipos:marca_filter' %}
それをjsフェッチ関数に渡すために完全なURLが必要でした。これがお役に立てば幸いです。
私はこれが古い質問であることを知っています。しかし、私はまだ多くの人がこれに遭遇すると思います。
デフォルトのDjango機能を補足するライブラリがいくつかあります。私はいくつか試しました。絶対URLを逆参照するときは、次のライブラリが好きです。
https://github.com/fusionbox/django-absoluteuri
ドメイン、プロトコル、パスを簡単にまとめることができるので、もう1つ私が気に入っています。
https://github.com/RRMoelker/django-full-url
このライブラリを使用すると、テンプレートに必要なものを簡単に記述できます。例:
{{url_parts.domain}}
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
設定として利用可能なABSOLUTE_URL_OVERRIDESもあります
https://docs.djangoproject.com/en/2.1/ref/settings/#absolute-url-overrides
しかし、それはget_absolute_url()をオーバーライドするため、望ましくない場合があります。
このためだけにサイトフレームワークをインストールしたり、ここで説明したリクエストオブジェクトに依存するその他のことを行う代わりに、models.pyに配置することをお勧めします。
BASE_URLをsettings.pyで定義し、models.pyにインポートして、get_truly_absolute_url()を定義する抽象クラスを作成します(またはすでに使用しているクラスに追加します)。それは次のように簡単かもしれません:
def get_truly_absolute_url(self):
return BASE_URL + self.get_absolute_url()
それをサブクラス化すれば、どこでも使用できます。
他の回答で述べたように、にrequest.build_absolute_uri()
アクセスできれば完璧です。異なるURLが異なるデータベースを指す限りrequest
、sites
フレームワークは素晴らしいです。
ただし、使用例は少し異なりました。ステージングサーバーと運用サーバーは同じデータベースにアクセスしましたが、get_current_site
どちらもデータベースの最初のサーバーを返しsite
ました。これを解決するには、何らかの環境変数を使用する必要があります。1)環境変数(などos.environ.get('SITE_URL', 'localhost:8000')
)または2)SITE_ID
サーバーごとに異なると異なるsettings.pyを使用できます。
うまくいけば、誰かがこれを便利にするでしょう!
次のものも使用できます。
import socket
socket.gethostname()
これは私にとってはうまく機能しています
私はそれがどのように機能するか完全にはわかりません。これはもう少し低レベルであり、サーバーのホスト名を返すと思います。これは、ユーザーがページにアクセスするために使用するホスト名とは異なる場合があります。