【问题标题】:Keeping original request link between redirects in Django?在 Django 中的重定向之间保持原始请求链接?
【发布时间】:2014-01-18 14:17:16
【问题描述】:

我确实使用了默认的 django.core.context_processors.request 模板上下文处理器,因此我可以在我的 Django 模板中访问 request HttpRequest 实例。

一种用途是检索原始发件人网址:

import re

nexturl_re = re.compile('\?next=(.+)$')

@register.simple_tag(takes_context=True)
def get_previous_url(context):
    try:
        return shop_base + \
            nexturl_re.search( context['request'].get_full_path() ).group(1)
    except (IndexError, AttributeError):
        return shop_base + '/'

我确实使用它从发件人网址中提取参数。

问题在于某些视图执行 http 重定向到另一个视图,因此 ?next= 之后的原始可选参数丢失。

有什么方法可以保留/传递特定视图的原始 url 吗? 例如,smart.smart_add 视图的 url 调度执行重定向。它不接受可选的关键字参数。

from django.conf.urls import patterns

urlpatterns += patterns('satchmo_store.shop.views',
    (r'^add/$', 'smart.smart_add', {}, 'satchmo_smart_add'),

除了完全重写原来的视图函数还有其他方法吗?

谢谢。

更新 根据abstractpaper的回答,问题解决如下:

  1. 编写了一个中间件类来传递重定向响应的 url 参数:
    import re
    
    nexturlopt_re = re.compile('(\?next=.+)$')
    
    class ForwardUrlArguments(object):
        def process_response(self, request, response):
            if response.status_code in (301, 302, …):
                new_location = response.get('Location')
                if new_location:
                    try:
                        new_location += nexturlopt_re.search(
                                request.get_full_path() ).group(1)
                    except (IndexError, AttributeError):
                        pass
                response['Location'] = new_location
    
            return response
    
  2. 在视图文件中装饰特定方法以应用中间件的响应:
    from django.utils.decorators import decorator_from_middleware
    
    forward_urlargs = decorator_from_middleware(ForwardUrlArguments)
    
    @forward_urlargs
    def account_signin(request):
        …
    
    @forward_urlargs
    def cart_smart_add(request):
        …
    
    @forward_urlargs
    def cart_set_quantity(request):
        return cart.set_quantity(request)   # wrapped a library function
    

【问题讨论】:

    标签: python django satchmo


    【解决方案1】:

    您可以编写 Middleware 来捕获 HTTP 301 请求并传递查询参数。

    【讨论】:

    • 这不是一个坏主意,但对于这种特定情况来说有点重量级。
    • 考虑到它只会为 HTTP 301 请求执行,它不会很重。当然,有 if 条件检查,但这真的很小。
    • 当没有其他人会添加更直接的解决方案时,我会将您的作为接受的答案。
    • decorator_from_middleware 装饰器,您可以使用它来基于视图应用中间件,但是我不确定您是否可以将它用于您的用例,因为您需要将它应用到拦截正在进行的重定向调用或传入的 HTTP 301 请求的特定视图。
    猜你喜欢
    • 2011-08-29
    • 2017-06-01
    • 2017-01-06
    • 2013-08-03
    • 1970-01-01
    • 2013-01-26
    • 1970-01-01
    • 2012-04-19
    • 1970-01-01
    相关资源
    最近更新 更多