【问题标题】:Load external (absolute) URL in urlpatterns在 urlpatterns 中加载外部(绝对)URL
【发布时间】:2020-06-29 05:18:29
【问题描述】:

我想将 Django 中的 URL 模式与外部 URL 相关联,因为我的某些视图需要指向不同的子域。请注意,所有子域都使用完全相同的 Django 实例,所以我仍然在我的应用程序中引用本地视图。在某些情况下,我只需要将用户发送到不同的域。我已经考虑了站点框架,但还有其他因素阻止我使用它。解决方案似乎差不多了,但我有一个绊脚石。

我这样做:

urlpatterns += [
    path("https://subdomain.mywebsite.com/", include("site.urls")),
]

这项工作。但是,当我像这样生成我的 URL 时:

<a href="{% url "somepage" %}">link</a>

然后它导致:

<a href="/https://subdomain.mywebsite.com/record/">link</a>

也就是说,生成的网址前面有一个斜杠。除此之外,一切正常。我怎样才能摆脱那个?

【问题讨论】:

  • 你不能使用这样的 url 模式,这不是它们的设计目的。它们旨在用于为您的应用程序视图提供服务的路径
  • 让我更改示例 URL --- 该路径确实是我的应用程序视图的一部分,但它位于不同的域中。
  • 你能发布你的视图函数/基于类的视图吗?
  • 在不同的域上怎么样?您是在使用多租户的站点框架(因此是相同的 Django 应用程序,但被分割成多个部分),还是一起使用不同的 Django 实例?
  • 它是同一个 Django 实例(由于不相关的原因没有使用站点框架,但它是完全相同的 Django 实例)。

标签: django django-templates url-routing


【解决方案1】:

正如@Iain Shelvington 所说,不要像这样定义urlpatterns,它们旨在用于为您的应用程序视图提供服务的路径

一定是的,

urlpatterns += [
    path("", include("site.urls")),
        ^^^^ see, empty name
]

然后在你的模板中,

&lt;a href=<b>"https://subdomain.mywebsite.com{% url 'somepage' %}"</b>&gt;link&lt;/a&gt;

这将生成一个链接,

<a href="https://subdomain.mywebsite.com/record/">link</a>

【讨论】:

  • 请注意:正如我在帖子中阐明的那样,我 am 使用 urlpatterns 来提供应用程序视图。完全相同的应用程序用于两个不同的域,我想在某些情况下将人们发送到 other 域。
  • 快速提问,您尝试过我的解决方案吗?有错误?出现意外行为?
  • 顺便说一句,如果您遵循此答案,您将获得链接(正如我所提到的)无论(子)域
  • 感谢 Arakkal,但我无法在模板中对 URL 进行硬编码。这需要动态加载。
  • 但是我可以看到您在urls.py 中对域名进行了硬编码,这不是问题吗?如果不是,你能解释一下如何吗? (我只是想了解您的“确切情况”)
【解决方案2】:

我仍然无法对帖子发表评论,但其他的都是正确的。如果你想完全为一个子域或不同的域提供服务,你不想使用 URLConf。事实上,您需要一个的唯一原因是,您正在尝试为 Django 视图提供服务您不是。另一个网站是。

相反,如果您真的不想在模板中对域进行硬编码,那么在最初显示模板的 Django 视图中,您应该将 Django 视图中的上下文传递给您的模板,以便客户端看到它是硬编码的,但您的 Django 视图正在动态加载 url。

同样,这些 url 模板标签适用于您的 Django 正在服务的网站。如果 url conf 没有为该网站提供服务,那就不要打扰。

【讨论】:

    【解决方案3】:

    您需要将other domain 提供给上下文,以便所有模板都可以使用它。 创建文件 context_processors.py

    def new_domain_context_processor(request):
        return {
            'other_domain': 'YOUR_DOMAIN_URL',
        }
    

    在setting.py中

    TEMPLATES = [
        {
    ...
            'OPTIONS': {
    ...
                'context_processors': [
                    'django.template.context_processors.static',
                    'django.template.context_processors.media',
                    'django.template.context_processors.request',
    ...
                    'YOUR_APP.context_processors.new_domain_context_processor,
                ],
    ...
            },
        },
    ]
    

    之后,您可以在模板中使用{{ other_domain }}

    <a href="{{ other_domain }}{% url 'somepage' %}">link</a>
    

    【讨论】:

      【解决方案4】:

      让我们把它变成一个更具体的案例。假设我们使用一个帐户应用程序进行帐户管理,但在一个集中的子域“auth.example.com”上。我们已采取所有措施,通过在 settings.py 中设置适当的值来确保在我们的主站点“www.example.com”上可以读取会话和 CSRF cookie。此外,我们可以通过将REDIRECT_AUTH_TO_AUTH_SUBDOMAIN 设置为 False 来关闭此行为。

      from django.conf import settings
      from django.core.exceptions import MiddlewareNotUsed
      from django import http
      
      
      class AuthRedirectMiddleware:
          AUTH_SUBDOMAIN = "auth.example.com"
      
          def __init__(self, get_response=None):
              if not settings.REDIRECT_AUTH_TO_AUTH_SUBDOMAIN:
                  raise MiddlewareNotUsed
              self.get_reponse = get_response
      
          def __call__(self, request: http.HttpRequest):
              if request.get_full_path().startswith("/account/"):
                  host = request.get_host()
                  if host != self.AUTH_SUBDOMAIN:
                      url = request.build_absolute_uri().replace(host, self.AUTH_SUBDOMAIN)
                      return http.HttpResponseRedirect(url)
      
              return self.get_reponse()
      

      你的 urlconf 会有:

      urlpatterns = [
          path("account/", include("account.urls"),
          ...
      ]
      

      模板中的反向链接没有域名,而只是/account/login/,然后被重定向到 auth 子域。

      【讨论】:

        【解决方案5】:

        最好使用 Django 的 the "sites" framework 来代替。跟踪请求的域。只需在您的视图中使用Site.objects.get_current()

        还有django-subdomains“电池”用于您的目标,带有子域的反向 URL(参见下面的示例)。

        {% load subdomainurls %}
        
        {% url 'home' %}
        {% url 'home' 'subdomain' %}
        {% url 'home' subdomain='subdomain' %}
        {% url 'user-profile' username='ted' %}
        {% url 'user-profile' subdomain='subdomain' username='ted' %}
        

        或者您可以使用 Site in template ({{ site.domain }}) 或自定义 RequestContext 添加子域前缀。

        附:并且绝对不要将子域添加到url_patterns。他们用于匹配域之后的所有内容。

        【讨论】:

          【解决方案6】:

          请注意:正如我在帖子中阐明的那样,我使用 urlpatterns 来提供应用程序视图。完全相同的应用程序用于两个不同的域,我想在某些情况下将人员发送到另一个域。

          为什么不使用反向代理服务来重定向为 Nginx? 一般来说,最好直接指向 suburl 并在其中更改域视觉。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-06-27
            • 1970-01-01
            • 1970-01-01
            • 2018-02-28
            • 1970-01-01
            • 2020-10-11
            • 1970-01-01
            相关资源
            最近更新 更多