Sites modülü olmadanhttps://example.com/some/path
Django'daki tam / mutlak URL'yi (ör. ) Nasıl edinebilirim ? Bu sadece aptalca ... URL'yi takmak için DB'mi sorgulamam gerekmiyor!
İle kullanmak istiyorum reverse()
.
Sites modülü olmadanhttps://example.com/some/path
Django'daki tam / mutlak URL'yi (ör. ) Nasıl edinebilirim ? Bu sadece aptalca ... URL'yi takmak için DB'mi sorgulamam gerekmiyor!
İle kullanmak istiyorum reverse()
.
Yanıtlar:
Talep üzerine kullanışlı request.build_absolute_uri () yöntemini kullanın , göreli URL'yi iletin ve size tam bir URL verecektir.
Varsayılan olarak, için mutlak URL request.get_full_path()
döndürülür, ancak onu mutlak bir URL'ye dönüştürmek için ilk bağımsız değişken olarak göreli bir URL iletebilirsiniz.
{{ request.build_absolute_uri }}{{ object.get_absolute_url }}
- ve heyho, tam url.
{% if request.is_secure %}https://{% else %}http://{% endif %}{{ request.get_host }}{{ object.get_absolute_url }}
çünkü bir eğik çizgi vardı ve URL'de çift eğik çizgi ile sonuçlanan bir eğik {{ request.build_absolute_uri }}
çizgi ile {{ object.get_absolute_url }}
başladı.
Birlikte kullanmak reverse()
istiyorsanız bunu yapabilirsiniz:request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))
url_name
bunun yerine demek view_name
def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)
Ayrıca get_current_site
siteler uygulamasının ( from django.contrib.sites.models import get_current_site
) bir parçası olarak da kullanabilirsiniz . Bir istek nesnesi alır ve istek SITE_ID
varsa, settings.py içinde yapılandırdığınız site nesnesini varsayılan olarak kullanır None
. Site çerçevesini kullanma ile ilgili belgelerde daha fazla bilgi edinin
Örneğin
from django.contrib.sites.shortcuts import get_current_site
request = None
full_url = ''.join(['http://', get_current_site(request).domain, obj.get_absolute_url()])
Oldukça kompakt / düzenli değil request.build_absolute_url()
, ancak istek nesneleri kullanılamadığında kullanılabilir ve varsayılan bir site URL'niz var.
django.contrib.sites
Gözlerinde farklı INSTALLED_APPS
, hiç DB vurmak olmaz ve (bkz Request nesnesi dayalı bilgi vermek get_current_site )
build_absolute_uri
yine de daha kolay ve daha temiz bir çözüm gibi görünüyor.
Erişim request
sağlayamıyorsanız get_current_site(request)
, buradaki bazı çözümlerde önerildiği gibi kullanamazsınız . Yerel Sites çerçevesinin bir kombinasyonunu ve get_absolute_url
bunun yerine kullanabilirsiniz. Yönetici içinde en az bir Site oluşturun , modelinizde bir get_absolute_url () yöntemi bulunduğundan emin olun , ardından:
>>> 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
için None
veya çağrı get_current_site(None)
.
Veritabanına vurmak istemiyorsanız, bunu bir ayarla yapabilirsiniz. Ardından, her şablona eklemek için bir bağlam işlemcisi kullanın:
# 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
Bir Django şablonunda bunu çalışıyorsanız, ben küçücük PyPI paketi sunduk django-fullurl
Değiştirmek izin url
ve static
şablon etiketleri fullurl
ve fullstatic
bunun gibi,:
{% load fullurl %}
Absolute URL is: {% fullurl "foo:bar" %}
Another absolute URL is: {% fullstatic "kitten.jpg" %}
Bu rozetler umarım otomatik olarak güncel kalmalıdır:
Bir görünümde, elbette request.build_absolute_uri
bunun yerine kullanabilirsiniz .
request
, alan adını almak için hiçbir nesne olmamasıdır. Bu durumda, sites
etki alanını veritabanından alan çerçeveyi kullanmalısınız. Bkz django-absoluteuri
. Bu PyPI paketinin README'sinin "ayrıca bkz." Bölümünde.
Bir şablondan başka bir sayfaya eksiksiz bir bağlantı oluşturmak için şunu kullanabilirsiniz:
{{ request.META.HTTP_HOST }}{% url 'views.my_view' my_arg %}
request.META.HTTP_HOST ana bilgisayar adını ve url göreli adı verir. Şablon motoru daha sonra bunları tam bir URL'ye birleştirir.
http
bu bağlamda) ve ://
URL'nin bir kısmı eksik olduğundan tam bir URL sağlamayacak .
Yine başka bir yol. Kullanabilirsinbuild_absolute_uri()
Gözlerinde farklı view.py
ve şablona geçmek.
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)
eşittir request.build_absolute_uri()
değil mi?
Şablonumda bu benim için çalıştı:
{{ request.scheme }}:{{ request.META.HTTP_HOST }}{% url 'equipos:marca_filter' %}
Bir js getirme işlevine geçmek için tam url gerekli. Umarım bu sana yardımcı olur.
Bunun eski bir soru olduğunu biliyorum. Ama bence insanlar hala bununla çok uğraşıyorlar.
Varsayılan Django işlevselliğini destekleyen birkaç kütüphane var. Birkaçını denedim. Mutlak URL'leri tersine çevirirken aşağıdaki kütüphaneyi beğendim:
https://github.com/fusionbox/django-absoluteuri
Bir etki alanı, protokol ve yolu kolayca bir araya getirebileceğiniz için sevdiğim başka bir tane:
https://github.com/RRMoelker/django-full-url
Bu kütüphane, şablonunuzda istediğinizi yazmanıza olanak tanır, örneğin:
{{url_parts.domain}}
Django REST çerçevesini kullanıyorsanız, adresinden reverse işlevini kullanabilirsiniz rest_framework.reverse
. django.core.urlresolvers.reverse
Tam URL oluşturmak için bir istek parametresi kullanması dışında, bunun davranışıyla aynıdır .
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,))
Yalnızca REST çerçevesinde kullanılabilirlikten bahsetmek için düzenlendi
request=request
. Ayrıca, istek burada belgelenmiş gibi görünmüyor docs.djangoproject.com/en/1.9/ref/urlresolvers/#reverse
Anladım:
wsgiref.util.request_uri(request.META)
Şema, ana bilgisayar, bağlantı noktası yolu ve sorgu ile tam uri alın.
Ayrıca ayar olarak ABSOLUTE_URL_OVERRIDES kullanılabilir
https://docs.djangoproject.com/en/2.1/ref/settings/#absolute-url-overrides
Ancak bu, istenmeyebilecek get_absolute_url () yöntemini geçersiz kılar.
Siteler çerçevesini sadece bunun için yüklemek veya burada belirtilen istek nesnesine dayanan diğer bazı şeyleri yapmak yerine, bence daha iyi bir çözüm bunu models.py'ye yerleştirmektir.
Settings.py'de BASE_URL tanımlayın, ardından models.py dosyasına aktarın ve get_truly_absolute_url () öğesini tanımlayan soyut bir sınıf yapın (veya zaten kullanmakta olduğunuz bir tanesine ekleyin). Bu kadar basit olabilir:
def get_truly_absolute_url(self):
return BASE_URL + self.get_absolute_url()
Alt sınıflandırın ve şimdi her yerde kullanabilirsiniz.
Diğer cevaplarda belirtildiği gibi request.build_absolute_uri()
, erişiminiz varsa request
vesites
farklı URL'ler farklı veritabanlarına işaret ettiği sürece çerçeve harikadır.
Ancak benim kullanım durumum biraz farklıydı. Evreleme sunucum ve üretim sunucum aynı veritabanına erişiyor, ancak get_current_site
her ikisi site
de veritabanındaki ilk veritabanını döndürdü . Bu sorunu çözmek için bir tür ortam değişkeni kullanmanız gerekir. Farklı sunucular VE farklı ayarlar için 1) bir ortam değişkeni (bir şey gibi os.environ.get('SITE_URL', 'localhost:8000')
) veya 2) farklı SITE_ID
s kullanabilirsiniz .
Umarım birisi bunu faydalı bulacaktır!
Ben bir başarı sayfası için mutlak bir URI oluşturmak için bakıyordu çünkü bu iş parçacığı geldi. request.build_absolute_uri()
bana şimdiki görüşüm için bir URI verdi ama başarı görünümüm için URI almak için aşağıdakileri kullandım ....
request.build_absolute_uri (ters ( 'success_view_name'))
Ayrıca kullanabilirsiniz:
import socket
socket.gethostname()
Bu benim için iyi çalışıyor,
Nasıl çalıştığından tam olarak emin değilim. Bunun biraz daha düşük bir düzey olduğuna ve sayfanıza ulaşmak için kullanıcı tarafından kullanılan ana makine adından farklı olabilecek sunucu ana makine adınızı döndüreceğine inanıyorum.