Bagaimana saya bisa mendapatkan URL penuh / absolut (misalnya https://example.com/some/path
) di Django tanpa modul Situs ? Itu konyol ... Saya tidak perlu meminta DB saya untuk mengambil URL!
Saya ingin menggunakannya reverse()
.
Bagaimana saya bisa mendapatkan URL penuh / absolut (misalnya https://example.com/some/path
) di Django tanpa modul Situs ? Itu konyol ... Saya tidak perlu meminta DB saya untuk mengambil URL!
Saya ingin menggunakannya reverse()
.
Jawaban:
Gunakan metode request.build_absolute_uri () yang berguna berdasarkan permintaan, berikan url relatifnya dan itu akan memberi Anda satu penuh.
Secara default, URL absolut untuk request.get_full_path()
dikembalikan, tetapi Anda dapat memberikan URL relatif sebagai argumen pertama untuk mengubahnya menjadi URL absolut.
{{ request.build_absolute_uri }}{{ object.get_absolute_url }}
- dan hei, url lengkap.
{% if request.is_secure %}https://{% else %}http://{% endif %}{{ request.get_host }}{{ object.get_absolute_url }}
karena {{ request.build_absolute_uri }}
memiliki garis miring dan {{ object.get_absolute_url }}
mulai dengan garis miring menghasilkan garis miring ganda di URL.
Jika Anda ingin menggunakannya, reverse()
Anda dapat melakukan ini:request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))
url_name
bukannya view_name
)
def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)
Anda juga dapat menggunakan get_current_site
sebagai bagian dari aplikasi situs ( from django.contrib.sites.models import get_current_site
). Dibutuhkan objek permintaan, dan default ke objek situs yang telah Anda konfigurasikan SITE_ID
di settings.py jika permintaan None
. Baca lebih lanjut dalam dokumentasi untuk menggunakan kerangka kerja situs
misalnya
from django.contrib.sites.shortcuts import get_current_site
request = None
full_url = ''.join(['http://', get_current_site(request).domain, obj.get_absolute_url()])
Ini tidak kompak / rapi request.build_absolute_url()
, tetapi dapat digunakan ketika objek permintaan tidak tersedia, dan Anda memiliki url situs default.
django.contrib.sites
di Anda INSTALLED_APPS
, itu tidak akan memukul DB sama sekali, dan memberikan informasi berdasarkan objek Request (lihat get_current_site )
build_absolute_uri
masih terlihat seperti solusi yang lebih mudah dan bersih.
Jika Anda tidak dapat mengakses request
maka Anda tidak dapat menggunakan get_current_site(request)
seperti yang disarankan dalam beberapa solusi di sini. Anda dapat menggunakan kombinasi kerangka Situs asli dan get_absolute_url
sebagai gantinya. Siapkan setidaknya satu Situs di admin, pastikan model Anda memiliki metode get_absolute_url () , lalu:
>>> 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
ke None
atau panggilan get_current_site(None)
.
Jika Anda tidak ingin membuka database, Anda bisa melakukannya dengan pengaturan. Kemudian, gunakan pengolah konteks untuk menambahkannya ke setiap templat:
# 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
Jika Anda mencoba melakukan ini di templat Django, saya telah merilis paket PyPI kecil django-fullurl
untuk memungkinkan Anda mengganti url
dan static
templat tag dengan fullurl
dan fullstatic
, seperti ini:
{% load fullurl %}
Absolute URL is: {% fullurl "foo:bar" %}
Another absolute URL is: {% fullstatic "kitten.jpg" %}
Lencana-lencan ini semoga tetap diperbarui secara otomatis:
Dalam sebuah tampilan, Anda tentu saja dapat menggunakannya request.build_absolute_uri
.
request
objek untuk mendapatkan nama domain. Dalam hal ini, Anda harus menggunakan sites
kerangka sebagai gantinya, yang mendapatkan nama domain dari database. Lihat django-absoluteuri
, disebutkan di bagian "lihat juga" dari README dari paket PyPI ini.
Untuk membuat tautan lengkap ke halaman lain dari templat, Anda dapat menggunakan ini:
{{ request.META.HTTP_HOST }}{% url 'views.my_view' my_arg %}
request.META.HTTP_HOST memberikan nama host, dan url memberikan nama relatif. Mesin templat kemudian menggabungkannya menjadi url lengkap.
http
dalam konteks ini) dan ://
bagian dari URL, sehingga tidak akan memberikan url lengkap .
Namun cara lain. Anda bisa menggunakannya build_absolute_uri()
di dalam view.py
dan meneruskannya ke templat.
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)
setara dengan request.build_absolute_uri()
bukan?
Periksa Request.META
kamus yang masuk. Saya pikir itu memiliki nama server dan port server.
Ini berfungsi untuk saya di templat saya:
{{ request.scheme }}:{{ request.META.HTTP_HOST }}{% url 'equipos:marca_filter' %}
Saya membutuhkan url lengkap untuk meneruskannya ke fungsi js fetch. Saya harap ini membantu Anda.
Saya tahu ini adalah pertanyaan lama. Tapi saya pikir orang masih sering mengalami hal ini.
Ada beberapa perpustakaan di luar sana yang melengkapi fungsi Django default. Saya sudah mencoba beberapa. Saya suka perpustakaan berikut ketika membalikkan referensi URL absolut:
https://github.com/fusionbox/django-absoluteuri
Satu lagi yang saya suka karena Anda dapat dengan mudah mengumpulkan domain, protokol, dan jalur:
https://github.com/RRMoelker/django-full-url
Pustaka ini memungkinkan Anda untuk menuliskan apa yang Anda inginkan di templat, misalnya:
{{url_parts.domain}}
Jika Anda menggunakan kerangka kerja Django REST, Anda dapat menggunakan fungsi sebaliknya dari rest_framework.reverse
. Ini memiliki perilaku yang sama dengan django.core.urlresolvers.reverse
, kecuali bahwa ia menggunakan parameter permintaan untuk membangun URL lengkap.
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,))
Diedit untuk menyebutkan ketersediaan hanya dalam kerangka REST
request=request
. Itu juga tidak tampak seperti permintaan didokumentasikan di sini docs.djangoproject.com/en/1.9/ref/urlresolvers/#reverse
Saya mendapatkannya:
wsgiref.util.request_uri(request.META)
Dapatkan uri lengkap dengan skema, host, jalur port, dan permintaan.
Ada juga ABSOLUTE_URL_OVERRIDES yang tersedia sebagai pengaturan
https://docs.djangoproject.com/en/2.1/ref/settings/#absolute-url-overrides
Tapi itu menimpa get_absolute_url (), yang mungkin tidak diinginkan.
Alih-alih menginstal kerangka situs hanya untuk ini atau melakukan beberapa hal lain yang disebutkan di sini yang bergantung pada objek permintaan, saya pikir solusi yang lebih baik adalah menempatkan ini di models.py
Tentukan BASE_URL di settings.py, lalu impor ke dalam models.py dan buat kelas abstrak (atau tambahkan ke yang sudah Anda gunakan) yang mendefinisikan get_truly_absolute_url (). Ini bisa sesederhana:
def get_truly_absolute_url(self):
return BASE_URL + self.get_absolute_url()
Subkelas dan sekarang Anda dapat menggunakannya di mana saja.
Seperti disebutkan dalam jawaban lain, request.build_absolute_uri()
sangat cocok jika Anda memiliki akses ke request
, dansites
kerangka kerjanya bagus selama URL yang berbeda menunjuk ke database yang berbeda.
Namun, use case saya sedikit berbeda. Server pementasan saya dan server produksi mengakses database yang sama, tetapi get_current_site
keduanya mengembalikan yang pertama site
dalam database. Untuk mengatasi ini, Anda harus menggunakan semacam variabel lingkungan. Anda dapat menggunakan 1) variabel lingkungan (seperti os.environ.get('SITE_URL', 'localhost:8000')
) atau 2) berbeda SITE_ID
untuk server yang berbeda DAN pengaturan yang berbeda.py .
Semoga seseorang akan menemukan ini berguna!
Saya menemukan utas ini karena saya ingin membangun URI absolut untuk halaman sukses. request.build_absolute_uri()
memberi saya URI untuk tampilan saya saat ini tetapi untuk mendapatkan URI untuk tampilan kesuksesan saya, saya menggunakan yang berikut ....
request.build_absolute_uri (membalikkan ('success_view_name'))
Anda juga bisa menggunakan:
import socket
socket.gethostname()
Ini bekerja dengan baik untuk saya,
Saya tidak sepenuhnya yakin cara kerjanya. Saya percaya ini sedikit lebih rendah dan akan mengembalikan nama host server Anda, yang mungkin berbeda dari nama host yang digunakan oleh pengguna Anda untuk sampai ke halaman Anda.