如何在Django 没有Sites模块中获得完整/绝对的URL(例如https://example.com/some/path) ?这太愚蠢了……我不需要查询我的数据库来抓取URL!
https://example.com/some/path
我想与reverse()一起使用它。
reverse()
检查输入的Request.META字典。我认为它有服务器名和服务器端口。
Request.META
在请求时使用方便的request.build_absolute_uri ()方法,将相对url传递给它,它会给你一个完整的url。
默认情况下,返回request.get_full_path()的绝对URL,但您可以将相对URL作为第一个参数传递给它,以将其转换为绝对URL。
request.get_full_path()
>>> request.build_absolute_uri() 'https://example.com/music/bands/the_beatles/?print=true' >>> request.build_absolute_uri('/bands/?print=true') 'https://example.com/bands/?print=true'
你也可以使用get_current_site作为站点应用程序(from django.contrib.sites.models import get_current_site)的一部分。它接受一个请求对象,如果request是None,则默认为您在settings.py中使用SITE_ID配置的站点对象。在使用网站框架文档中阅读更多内容
get_current_site
from django.contrib.sites.models import get_current_site
None
SITE_ID
如。
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时,它是可用的。
request.build_absolute_url()
你可以试试"request.get_full_path()"
如果你想在reverse()中使用它,你可以这样做:request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))
request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))
如果你不能访问request,那么你就不能像这里的一些解决方案中推荐的那样使用get_current_site(request)。你可以使用本地Sites框架和get_absolute_url的组合。在管理中至少设置一个网站,确保你的模型有一个get_absolute_url ()方法,然后:
request
get_current_site(request)
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
如果你不想访问数据库,你可以通过设置来实现。然后,使用上下文处理器将其添加到每个模板:
# 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>
要从模板创建到另一个页面的完整链接,您可以使用以下命令:
\{\{ request.META.HTTP_HOST }}{% url 'views.my_view' my_arg %}
request.META。HTTP_HOST给出主机名,url给出相对名。然后模板引擎将它们连接成一个完整的url。
还有另一种方式。你可以在你的view.py中使用build_absolute_uri()并将它传递给模板。
view.py
build_absolute_uri()
def index(request): baseurl = request.build_absolute_uri() return render_to_response('your-template.html', { 'baseurl': baseurl })
your-template.html
\{\{ baseurl }}
我知道这是一个老问题。但我认为人们仍然经常遇到这种情况。
有几个库可以补充Django的默认功能。我试过一些。当反向引用绝对url时,我喜欢以下库:
https://github.com/fusionbox/django-absoluteuri
另一个我喜欢的是,因为你可以很容易地把域、协议和路径放在一起:
https://github.com/RRMoelker/django-full-url
这个库允许你在模板中简单地写你想要的东西,例如:
\{\{url_parts.domain}}
request.get_host()会给你域名。
request.get_host()
你还可以使用:
import socket socket.gethostname()
这对我来说很好,
我不太清楚它是怎么运作的。我相信这是更低级的,它将返回您的服务器主机名,这可能与您的用户访问您的页面所使用的主机名不同。
我明白了:
wsgiref.util.request_uri(request.META)
获取包含模式、主机、端口路径和查询的完整uri。
如果你正在使用django REST框架,你可以使用rest_framework.reverse的反向函数。它具有与django.core.urlresolvers.reverse相同的行为,除了它使用一个请求参数来构建一个完整的URL。
rest_framework.reverse
django.core.urlresolvers.reverse
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框架中的可用性
在你看来,只需这样做:
base_url = "{0}://{1}{2}".format(request.scheme, request.get_host(), request.path)
试试下面的代码:
\{\{ request.scheme }}://\{\{ request.META.HTTP_HOST }}
django-fullurl
如果你想在Django模板中这样做,我已经发布了一个小的PyPI包django-fullurl,让你用fullurl和fullstatic替换url和static模板标签,就像这样:
fullurl
fullstatic
url
static
{% load fullurl %} Absolute URL is: {% fullurl "foo:bar" %} Another absolute URL is: {% fullstatic "kitten.jpg" %}
这些徽章应该自动保持最新:
.
在视图中,你当然可以使用request.build_absolute_uri来代替。
request.build_absolute_uri
这在我的模板中很管用:
\{\{ request.scheme }}://\{\{ request.META.HTTP_HOST }}{% url 'equipos:marca_filter' %}
我需要完整的url传递给一个js获取函数。 我希望这对你有帮助。
还有ABSOLUTE_URL_OVERRIDES可用作为设置
https://docs.djangoproject.com/en/2.1/ref/settings/#absolute-url-overrides
但这将覆盖get_absolute_url(),这可能是不可取的。
我认为更好的解决方案是把它放在models.py中,而不是仅仅为此安装sites框架,或者做一些这里提到的依赖于request对象的其他事情
在settings.py中定义BASE_URL,然后将其导入models.py并创建一个抽象类(或将其添加到您已经在使用的类中),该类定义get_truly_absolute_url()。它可以很简单:
def get_truly_absolute_url(self): return BASE_URL + self.get_absolute_url()
子类化它,现在你可以在任何地方使用它。
正如在其他答案中提到的,如果你可以访问request, request.build_absolute_uri()是完美的,而sites框架是伟大的,只要不同的url指向不同的数据库。
request.build_absolute_uri()
sites
然而,我的用例略有不同。我的登台服务器和生产服务器访问同一个数据库,但是get_current_site都返回了数据库中的第一个site。要解决这个问题,必须使用某种环境变量。你可以使用1)一个环境变量(类似os.environ.get('SITE_URL', 'localhost:8000'))或2)不同服务器的不同__abc5和不同settings.py。
site
os.environ.get('SITE_URL', 'localhost:8000')
希望有人会觉得这有用!
我遇到这个线程是因为我正在寻找为成功页面构建一个绝对URI。request.build_absolute_uri()给了我当前视图的URI,但为了获得我的成功视图的URI,我使用了以下....
request.build_absolute_uri(反向(success_view_name))
你可以传递request reverse('view-name', request=request)或者用build_absolute_uri request.build_absolute_uri(reverse('view-name'))将reverse()括起来
reverse('view-name', request=request)
request.build_absolute_uri(reverse('view-name'))
<div class='col-12 col-md-6'> <p class='lead'>Login</p> {% include 'accounts/snippets/form.html' with form=login_form next_url=request.build_absolute_uri %} </div>
例如,在这里,我说加载表单,并告诉表单,下一个URL是当前的URL,这段代码呈现
如果有人对获取带有参数在模板中的绝对反向url感兴趣,最简洁的方法是通过扩展和使用现有默认代码创建自己的{% url %} 模板标签的绝对版本。
{% url %}
这是我的代码:
from django import template from django.template.defaulttags import URLNode, url register = template.Library() class AbsURLNode(URLNode): def __init__(self, view_name, args, kwargs, asvar): super().__init__(view_name, args, kwargs, asvar) def render(self, context): url = super().render(context) request = context['request'] return request.build_absolute_uri(url) @register.tag def abs_url(parser, token): urlNode = url(parser, token) return AbsURLNode( urlNode.view_name, urlNode.args, urlNode.kwargs, urlNode.asvar )
在模板中的使用:
{% load wherever_your_stored_this_tag_file %} {% abs_url 'view_name' parameter %}
将渲染(示例):
http://example.com/view_name/parameter/
而不是
/view_name/parameter/
class WalletViewSet(mixins.ListModelMixin, GenericViewSet): serializer_class = WalletSerializers pagination_class = CustomPaginationInvestment def get_queryset(self): ###################################################### print(self.request.build_absolute_uri()) ##################################################### wallet, created = Wallet.objects.get_or_create(owner=self.request.user) return Wallet.objects.filter(id=wallet.id)
你得到这样的输出
http://localhost:8000/v1/wallet HTTP GET /v1/wallet 200 [0.03, 127.0.0.1:41608]
不是绝对的url,但我正在寻找只是得到主机。如果你想在view.py中获得host,你可以这样做
def my_view(request): host = f"{ request.scheme }://{ request.META.get('HTTP_HOST') }"
在做一个项目的时候,我学会了在Django中获取完整/绝对的URL。
如果你的URL在地址栏中是这样的:
https://stackoverflow.com/questions/2345708
如果你想把上面的URL显示给你的模板。
\{\{ request.path }}
#Without GET parameters.
\{\{ request.get_full_path }}
#with GET parameters
对于上面的两个代码,这将打印在你的模板中
questions/2345708
而且另一种获取完整URL的方法是:
\{\{request.build_absolute_uri}}
这将打印在你的模板将是:
我使用这个代码:
request.build_absolute_uri('/')[:-1]
回应:
https://yourdomain.com
在django中使用这个请求对象