Django的重定向应用程序不适用于URL参数 [英] Django's redirects app doesn't work with URL parameters
问题描述
我最近使用以下命令在我的网站上安装了Django的默认重定向应用指定的确切说明:
I recently installed Django's default redirects app on my site using the exact instructions specified:
- 已安装确保django.contrib.sites框架。
- 已添加'django.contrib。
- 已将'django.contrib.redirects.middleware.RedirectFallbackMiddleware'添加到MIDDLEWARE。
- 使用manage.py migration迁移了数据库。
- Ensured django.contrib.sites framework is installed.
- Added 'django.contrib.redirects' to INSTALLED_APPS.
- Added 'django.contrib.redirects.middleware.RedirectFallbackMiddleware' to MIDDLEWARE.
- 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 $ c
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屋!