如何在Django中获取完整/绝对URL(带域名)?

mpe*_*pen 348 django

如何https://example.com/some/path没有Sites模块的情况下获取 Django中的完整/绝对URL(例如)?那真是太傻了......我不需要查询我的数据库来获取URL!

我想用它reverse().

Dmi*_*nko 484

根据请求使用方便的request.build_absolute_uri()方法,将相关网址传递给它,它会给你一个完整的.

默认情况下,request.get_full_path()返回绝对URL ,但您可以将相对URL作为第一个参数传递给它,以将其转换为绝对URL.

  • 在模板中(你不能给出参数)你可以这样做:`{{request.build_absolute_uri}} {{object.get_absolute_url}}` - 和heyho,完整网址. (66认同)
  • #之后的所有内容都没有传递给服务器,它只是浏览器功能 (38认同)
  • 如果我无法访问请求怎么办?就像在Django-REST-Framework的Serializers中一样? (14认同)
  • 我不得不使用`{%if request.is_secure%} https:// {%else%} http:// {%endif%} {{request.get_host}} {{object.get_absolute_url}}`因为`{{ request.build_absolute_uri}}`有一个尾部斜杠,`{object.get_absolute_url}}`以斜杠开头,导致URL中出现双斜杠. (14认同)
  • 那个网址怎么样:http:// localhost/home /#/ test?我只能看到http:// localhost/home /.如何在*sharp*之后看到该部分? (3认同)
  • 对于 django 中请求对象可用的大多数地方,这是一个很好的答案,但 Darb 的答案 http://stackoverflow.com/questions/2345708/how-can-i-get-the-full-absolute-url-with-domain- in-django/8817935#8817935 非常适用于信号处理等应用程序,以在电子邮件中生成链接等。当您手头没有请求对象时。 (2认同)
  • 如果get_absolute_url总是有一个斜杠,我觉得像这样将它切下来是比较干净的:{{request.build_absolute_uri}} {{object.get_absolute_url | slice:“ 1:”}} (2认同)
  • @minder 要从 Django-rest-framework 获取请求,请在序列化程序函数调用中: request = self.context.get('request', None) (2认同)
  • 我收到以下错误:`ipdb> HttpRequest.build_absolute_uri(la_url) *** AttributeError: 'str' object has no attribute 'get_full_path'` (2认同)

小智 85

如果你想和它一起使用,reverse()你可以这样做:request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))

  • 谢谢你的回答.没有比编码本身更好的了.(另外,你可能意味着`url_name`而不是`view_name`) (3认同)
  • @Anupam reverse()定义为:`def reverse(viewname,urlconf = None,args = None,kwargs = None,current_app = None)` (3认同)
  • 当您有请求对象(例如在视图上)并且 url 用于 get 请求时,这对于构建完整 url 非常有效,因此重定向 http -> https 仍然可以。当请求对象不可用时,这将不起作用。例如,在计划任务或异步任务中构造url。处理 post 请求的 url 和前端使用 https,而 django 通过代理处理请求 (3认同)

Dar*_*arb 56

您还可以将其get_current_site用作网站app(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()])
Run Code Online (Sandbox Code Playgroud)

它不像紧凑/整洁request.build_absolute_url(),但它可用于请求对象不可用,并且您有一个默认的站点URL.

  • 我相信我的问题具体说"没有网站模块".这会打击数据库吗? (4认同)
  • Sites 模块已被写入使用模块级缓存(即您不需要缓存框架)来缓存 Site 对象,因此 DB 应该只在 Web 进程第一次检索站点时被命中。如果你的 `INSTALLED_APPS` 中没有 `django.contrib.sites`,它根本不会命中 DB,并提供基于 Request 对象的信息(参见 [get_current_site](https://github.com /django/django/blob/1.3.X/django/contrib/sites/models.py#L86)) (3认同)
  • 如果您使用https,则不起作用.是的,您可以添加s,但是您是否在本地使用https进行开发?并且你总是知道,如果你有https但有时没有......? (2认同)

sha*_*ker 53

如果您无法访问,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/'
Run Code Online (Sandbox Code Playgroud)

https://docs.djangoproject.com/en/dev/ref/contrib/sites/#getting-the-current-domain-for-full-urls

  • 当您无权访问HttpRequest对象时,这非常方便.例如在任务,信号等 (7认同)
  • 在使用之前你应该启用站点框架https://docs.djangoproject.com/en/dev/ref/contrib/sites/#enabling-the-sites-framework (6认同)

sed*_*nym 19

如果您不想访问数据库,可以使用设置进行操作.然后,使用上下文处理器将其添加到每个模板:

# 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>
Run Code Online (Sandbox Code Playgroud)


小智 14

这在我的模板中对我有用:

{{ request.scheme }}://{{ request.META.HTTP_HOST }}{% url 'equipos:marca_filter' %}
Run Code Online (Sandbox Code Playgroud)

我需要完整的 url 将它传递给 js fetch 函数。我希望这对你有帮助。


Fli*_*imm 13

django-fullurl

如果你想做到这一点在Django模板,我已经发布了一个很小的安装包的PyPI django-fullurl让你更换urlstatic用模板标签fullurlfullstatic,如下所示:

{% load fullurl %}

Absolute URL is: {% fullurl "foo:bar" %}

Another absolute URL is: {% fullstatic "kitten.jpg" %}
Run Code Online (Sandbox Code Playgroud)

这些徽章应该有希望自动保持最新:

的PyPI 特拉维斯CI

在视图中,您当然可以使用request.build_absolute_uri.


lev*_*evi 10

在您看来,只需这样做:

base_url =  "{0}://{1}{2}".format(request.scheme, request.get_host(), request.path)
Run Code Online (Sandbox Code Playgroud)


Dou*_*haw 8

要从模板创建指向其他页面的完整链接,您可以使用以下命令:

{{ request.META.HTTP_HOST }}{% url 'views.my_view' my_arg %}
Run Code Online (Sandbox Code Playgroud)

request.META.HTTP_HOST给出主机名,url给出相对名称.然后模板引擎将它们连接成一个完整的URL.

  • 答案是缺少协议(在此上下文中为`http`)和URL的`://`部分,因此它不会提供_a完整的url_. (2认同)
  • 请求对象上有一个主机.不要直接检查元:https://docs.djangoproject.com/en/1.8/ref/request-response/#django.http.HttpRequest.get_host (2认同)

Sve*_*jek 8

还有另一种方式.你可以使用build_absolute_uri()view.py,并把它传递给模板.

view.py

def index(request):
    baseurl = request.build_absolute_uri()
    return render_to_response('your-template.html', { 'baseurl': baseurl })
Run Code Online (Sandbox Code Playgroud)

您-template.html

{{ baseurl }}
Run Code Online (Sandbox Code Playgroud)


Kug*_*gel 7

检查Request.META进来的字典.我认为它有服务器名称和服务器端口.

  • 请求对象上有一个主机.不要直接检查元:https://docs.djangoproject.com/en/1.8/ref/request-response/#django.http.HttpRequest.get_host (4认同)
  • 使用request.META ['HTTP_HOST'] (2认同)

Joh*_*hnG 6

如果您使用的是 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,))
Run Code Online (Sandbox Code Playgroud)

编辑以提及仅在 REST 框架中的可用性


小智 6

请尝试以下代码:

{{ request.scheme }}://{{ request.META.HTTP_HOST }}
Run Code Online (Sandbox Code Playgroud)


小智 5

我知道这是一个老问题.但我认为人们仍然会遇到这种情况.

有几个库可以补充默认的Django功能.我试了几个.反向引用绝对URL时,我喜欢以下库:

https://github.com/fusionbox/django-absoluteuri

我喜欢的另一个因为你可以轻松地将域,协议和路径放在一起是:

https://github.com/RRMoelker/django-full-url

该库允许您在模板中简单地编写您想要的内容,例如:

{{url_parts.domain}}
Run Code Online (Sandbox Code Playgroud)


Pow*_*tar 5

如果有人有兴趣在模板中使用参数获取绝对反向 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  )
Run Code Online (Sandbox Code Playgroud)

在模板中的用法:

{% load wherever_your_stored_this_tag_file %}
{% abs_url 'view_name' parameter %}
Run Code Online (Sandbox Code Playgroud)

将渲染(示例):

http://example.com/view_name/parameter/
Run Code Online (Sandbox Code Playgroud)

代替

/view_name/parameter/
Run Code Online (Sandbox Code Playgroud)