ฉันจะรับ URL แบบเต็ม / สัมบูรณ์ (เช่นhttps://example.com/some/path
) ใน Django โดยไม่มีโมดูล Sites ได้อย่างไร นั่นมันช่างงี่เง่า ... ฉันไม่จำเป็นต้องค้นหา DB เพื่อขัดขวาง URL!
reverse()
ฉันต้องการที่จะใช้กับ
ฉันจะรับ URL แบบเต็ม / สัมบูรณ์ (เช่นhttps://example.com/some/path
) ใน Django โดยไม่มีโมดูล Sites ได้อย่างไร นั่นมันช่างงี่เง่า ... ฉันไม่จำเป็นต้องค้นหา DB เพื่อขัดขวาง URL!
reverse()
ฉันต้องการที่จะใช้กับ
คำตอบ:
ใช้คำขอที่มีประโยชน์build_absolute_uri ()วิธีการตามคำขอผ่าน 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 }}
เริ่มต้นด้วยเครื่องหมายทับทำให้มีเครื่องหมายทับสองครั้งใน 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
ก็จะไม่ตีฐานข้อมูลที่ทุกคนและให้ข้อมูลที่อยู่บนพื้นฐานของการร้องขอวัตถุ (ดูget_current_site )
build_absolute_uri
ก็ยังดูเหมือนโซลูชันที่ง่ายกว่าและสะอาดกว่า
หากคุณไม่สามารถเข้าถึงได้request
คุณจะไม่สามารถใช้งานได้get_current_site(request)
ตามที่แนะนำในโซลูชันบางอย่างที่นี่ คุณสามารถใช้การรวมกันของเฟรมเวิร์กไซต์ดั้งเดิมและget_absolute_url
แทน ตั้งค่าอย่างน้อยหนึ่งไซต์ในผู้ดูแลระบบตรวจสอบให้แน่ใจว่าแบบจำลองของคุณมีเมธอด 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>
ในมุมมองของคุณเพียงทำสิ่งนี้:
base_url = "{0}://{1}{2}".format(request.scheme, request.get_host(), request.path)
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
กล่าวถึงในส่วน "ดูเพิ่มเติม" ของ README ของแพ็คเกจ PyPI นี้
หากต้องการสร้างลิงก์ที่สมบูรณ์ไปยังหน้าอื่นจากเทมเพลตคุณสามารถใช้สิ่งนี้:
{{ 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 })
ของคุณ template.html
{{ baseurl }}
HttpRequest.build_absolute_uri(request)
เทียบเท่ากับrequest.build_absolute_uri()
มันใช่มั้ย
ตรวจสอบRequest.META
พจนานุกรมที่เข้ามาฉันคิดว่ามันมีชื่อเซิร์ฟเวอร์และเซิร์ฟเวอร์พอร์ต
ลองรหัสต่อไปนี้:
{{ request.scheme }}://{{ request.META.HTTP_HOST }}
สิ่งนี้ใช้ได้กับฉันในเทมเพลตของฉัน:
{{ request.scheme }}:{{ request.META.HTTP_HOST }}{% url 'equipos:marca_filter' %}
ฉันต้องการ URL แบบเต็มเพื่อส่งต่อไปยังฟังก์ชันดึงข้อมูล js ฉันหวังว่านี่จะช่วยคุณได้
ฉันรู้ว่านี่เป็นคำถามเก่า แต่ฉันคิดว่าผู้คนยังคงวิ่งเข้าไปหาสิ่งนี้มากมาย
มีไลบรารีอยู่สองสามตัวที่เสริมการทำงานของ Django ที่เป็นค่าเริ่มต้น ฉันได้ลองมาสองสามครั้งแล้ว ฉันชอบห้องสมุดต่อไปนี้เมื่อย้อนกลับการอ้างอิง URL แบบสัมบูรณ์:
https://github.com/fusionbox/django-absoluteuri
อีกอันที่ฉันชอบเพราะคุณสามารถรวบรวมโดเมนโปรโตคอลและพา ธ ได้อย่างง่ายดายคือ:
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
ฉันเข้าใจแล้ว:
wsgiref.util.request_uri(request.META)
รับ uri แบบเต็มด้วย schema โฮสต์เส้นทางของพอร์ตและแบบสอบถาม
นอกจากนี้ยังมี 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()
นั้นสมบูรณ์แบบถ้าคุณสามารถเข้าถึงrequest
และsites
กรอบงานนั้นยอดเยี่ยมตราบใดที่ URL ต่าง ๆ ชี้ไปยังฐานข้อมูลที่แตกต่างกัน
อย่างไรก็ตามกรณีการใช้งานของฉันแตกต่างกันเล็กน้อย เซิร์ฟเวอร์ staging ของฉันและเซิร์ฟเวอร์ที่ใช้งานจริงเข้าถึงฐานข้อมูลเดียวกัน แต่get_current_site
ทั้งคู่คืนค่าแรกsite
ในฐานข้อมูล ในการแก้ไขปัญหานี้คุณต้องใช้ตัวแปรสภาพแวดล้อมบางประเภท คุณสามารถใช้ 1) ตัวแปรสภาพแวดล้อม (สิ่งที่ต้องการos.environ.get('SITE_URL', 'localhost:8000')
) หรือ 2) ที่แตกต่างกันSITE_ID
สำหรับเซิร์ฟเวอร์ที่แตกต่างกันและsettings.py ที่แตกต่างกัน
หวังว่าบางคนจะพบว่ามีประโยชน์นี้!
ฉันเจอชุดข้อความนี้เนื่องจากฉันต้องการสร้าง URI แบบสัมบูรณ์สำหรับหน้าความสำเร็จ request.build_absolute_uri()
ให้ URI แก่ฉันสำหรับมุมมองปัจจุบันของฉัน แต่เพื่อให้ได้ URI สำหรับมุมมองความสำเร็จของฉันฉันใช้สิ่งต่อไปนี้ ....
request.build_absolute_uri (ย้อนกลับ ( 'success_view_name'))
คุณยังสามารถใช้:
import socket
socket.gethostname()
มันใช้ได้ดีสำหรับฉัน
ฉันไม่แน่ใจทั้งหมดว่ามันทำงานอย่างไร ฉันเชื่อว่านี่เป็นระดับที่ต่ำกว่าเล็กน้อยและจะส่งคืนชื่อโฮสต์เซิร์ฟเวอร์ของคุณซึ่งอาจแตกต่างจากชื่อโฮสต์ที่ผู้ใช้ของคุณใช้เพื่อไปที่หน้าของคุณ