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_namebukannya view_name)
def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)
Anda juga dapat menggunakan get_current_sitesebagai 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_IDdi 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.sitesdi Anda INSTALLED_APPS, itu tidak akan memukul DB sama sekali, dan memberikan informasi berdasarkan objek Request (lihat get_current_site )
build_absolute_urimasih terlihat seperti solusi yang lebih mudah dan bersih.
Jika Anda tidak dapat mengakses requestmaka 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_urlsebagai 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
requestke Noneatau 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-fullurlJika Anda mencoba melakukan ini di templat Django, saya telah merilis paket PyPI kecil django-fullurluntuk memungkinkan Anda mengganti urldan statictemplat tag dengan fullurldan 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.
requestobjek untuk mendapatkan nama domain. Dalam hal ini, Anda harus menggunakan siteskerangka 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.
httpdalam konteks ini) dan ://bagian dari URL, sehingga tidak akan memberikan url lengkap .
Namun cara lain. Anda bisa menggunakannya build_absolute_uri()di dalam view.pydan 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.METAkamus 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_sitekeduanya mengembalikan yang pertama sitedalam 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_IDuntuk 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.