Django的重定向应用程序不适用于URL参数 [英] Django's redirects app doesn't work with URL parameters

查看:112
本文介绍了Django的重定向应用程序不适用于URL参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近使用以下命令在我的网站上安装了Django的默认重定向应用指定的确切说明:

I recently installed Django's default redirects app on my site using the exact instructions specified:


  1. 已安装确保django.contrib.sites框架。

  2. 已添加'django.contrib。

  3. 已将'django.contrib.redirects.middleware.RedirectFallbackMiddleware'添加到MIDDLEWARE。

  4. 使用manage.py migration迁移了数据库。

  1. Ensured django.contrib.sites framework is installed.
  2. Added 'django.contrib.redirects' to INSTALLED_APPS.
  3. Added 'django.contrib.redirects.middleware.RedirectFallbackMiddleware' to MIDDLEWARE.
  4. Migrated database using manage.py migrate.

当我的URL干净时,该应用程序运行良好,就像这样:

The app works great when my URL is clean, like so:


重定向设置:/ page /到/ redirect /

Redirect setting: /page/ to /redirect/

当我访问 https: //www.example.com/page/ =>重定向到 https://www.example.com/redirect/

When I visit https://www.example.com/page/ => redirects to https://www.example.com/redirect/

但是,将URL参数附加到我的URL末尾时,重定向无效,例如:

However, the redirects don't work when URL parameters are appended to the end of my URL, like so:


重定向设置:/ page /到/ redirect /

Redirect setting: /page/ to /redirect/

当我访问 https://www.example.com/page/?url_parameter=true =>抛出Http404错误(找不到页面)

When I visit https://www.example.com/page/?url_parameter=true => throws Http404 error (page not found)

理想情况下,我希望我的重定向保留URL参数,例如:

Ideally, I'd like my redirects to preserve URL parameters, like so:


重定向设置:/ page /到/ redirect /

Redirect setting: /page/ to /redirect/

当我访问 https://www.example.com/page/?url_parameter=true =>重定向到 https://www.example.com/redirect/?url_parameter=true

When I visit https://www.example.com/page/?url_parameter=true => redirects to https://www.example.com/redirect/?url_parameter=true

是否有一种方法可以强制重定向应用按照上述要求保留URL参数?

Is there a way to force the redirects app to preserve URL parameters per the above?

推荐答案

1。您需要编写自己的 CustomRedirectFallbackMiddleware 通过子类 django.contrib.redirects.middleware.RedirectFallbackMiddleware 并覆盖 process_response django.contrib.redirects.middleware.RedirectFallbackMiddleware 的$ c>方法。

1.You need to write your own CustomRedirectFallbackMiddleware by subclass django.contrib.redirects.middleware.RedirectFallbackMiddleware and override process_response method of django.contrib.redirects.middleware.RedirectFallbackMiddleware.

custom_redirect_middleware.py

custom_redirect_middleware.py

import urlparse

from django import http
from django.conf import settings
from django.contrib.redirects.models import Redirect
from django.contrib.sites.shortcuts import get_current_site
from django.contrib.redirects.middleware import RedirectFallbackMiddleware


class CustomRedirectFallbackMiddleware(RedirectFallbackMiddleware):
    response_gone_class = http.HttpResponseGone
    response_redirect_class = http.HttpResponsePermanentRedirect

    def process_response(self, request, response):
        if response.status_code != 404:
            return response

        full_path = request.get_full_path() 
        """ 
            Seperate query parameters and url if full absolute path contains 
            query parameters using python urlparse library       
        """
        parsed_url = None
        if "?" in full_path:
            parsed_url = urlparse.urlparse(full_path)
            # Now full path contains no query parameters
            full_path = parsed_url.path

        current_site = get_current_site(request)

        r = None
        try:
            r = Redirect.objects.get(site=current_site, old_path=full_path)
        except Redirect.DoesNotExist:
            pass
        if r is None and settings.APPEND_SLASH and not request.path.endswith('/'):
            try:
                if parsed_url is not None:
                    r = Redirect.objects.get(
                        site=current_site,
                        old_path= full_path + '/',
                        )
                else:
                    r = Redirect.objects.get(
                        site=current_site,
                        old_path=request.get_full_path(force_append_slash=True),
                        )
            except Redirect.DoesNotExist:
                pass

        if r is not None:
            if r.new_path == '':
                return self.response_gone_class()

            #Adding back the query parameters to redirecting path
            if parsed_url is not None:
                new_path_with_query_params = r.new_path + "?" + parsed_url.query
                return self.response_redirect_class(new_path_with_query_params)

            #Handles redirections for urls without query parameters
            return self.response_redirect_class(r.new_path)

        return response

在此 CustomRedirectFallbackMiddleware


i。只需将 URL参数 full_absolute_path 分开即可。

ii。接下来获得精确的 redirect_path ,它们分别为 full_absolute_path
形式 django.contrib.redirects 数据库。

ii. Next got exact redirect_path of separated full_absolute_path form django.contrib.redirects database.

iii。然后将与 full_absolute_path 分开的 URL参数附加到 redirect_path

iii. Then appended the URL parameters which separated from full_absolute_path is to redirect_path.

2。删除'django.contrib.redirects.middleware.RedirectFallbackMiddleware'从您的 settings.py 并将以下行添加到 settings.py <的 MIDDLEWARE / code>。

2.Remove 'django.contrib.redirects.middleware.RedirectFallbackMiddleware' from your settings.py and add below line to MIDDLEWARE of settings.py.

# Here base is my Django app name
'base.custom_redirect_middleware.CustomRedirectFallbackMiddleware'

所有波纹管情况都很好。

All the bellow cases working very fine.

没有URL参数。

带有一个URL参数。

With one URL paramter.

具有多个URL参数。

更新: 修复了网址不带斜杠时提高404的问题。

Update: Fixed raising of 404 when URL with no trailing slash.

希望这会有所帮助。

这篇关于Django的重定向应用程序不适用于URL参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆