Django的重定向应用程序不适用于URL参数

Sam*_*Sam 5 python django redirect

我最近使用指定的确切说明在我的网站上安装了Django的默认重定向应用程序

  1. 确保已安装django.contrib.sites框架。
  2. 已将“ django.contrib.redirects”添加到INSTALLED_APPS。
  3. 在MIDDLEWARE中添加了“ django.contrib.redirects.middleware.RedirectFallbackMiddleware”。
  4. 使用manage.py迁移的数据库。

当我的URL干净时,该应用程序运行良好,如下所示:

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

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

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

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

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

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

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

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

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

Ste*_*raj 5

1.您需要通过子类编写自己的CustomRedirectFallbackMiddlewaredjango.contrib.redirects.middleware.RedirectFallbackMiddleware并重写的process_response方法django.contrib.redirects.middleware.RedirectFallbackMiddleware

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

在这 CustomRedirectFallbackMiddleware

一世。简单地分离URL parametersfull_absolute_path

ii。接下来得到精确redirect_path的分离full_absolute_path 表格django.contrib.redirects数据库。

iii。然后附加与URL parameters分离full_absolute_path的到redirect_path

2.取出'django.contrib.redirects.middleware.RedirectFallbackMiddleware'settings.py以下行添加到MIDDLEWAREsettings.py

# Here base is my Django app name
'base.custom_redirect_middleware.CustomRedirectFallbackMiddleware'
Run Code Online (Sandbox Code Playgroud)

所有的波纹管情况都很好。

没有网址参数。

具有一个URL参数。

具有多个URL参数。

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

希望这可以帮助。