【问题标题】:Django redirect back to view from inside view decoratorDjango 从内部视图装饰器重定向回视图
【发布时间】:2016-04-04 17:27:38
【问题描述】:

我一直在努力让 Django 的 URL 重定向在装饰器中工作。考虑这个确保视图的id 参数是奇数的简单装饰器:

from django.conf import settings
from django.conf.urls import url
from django.shortcuts import redirect
from django.http import HttpResponse
from django.core.urlresolvers import reverse
from django.utils.decorators import available_attrs

from functools import wraps

def ensure_odd_id(view):
    @wraps(view, assigned=available_attrs(view))
    def inner(request, *args, **kwargs):
        id = int(kwargs.get('id'))

        if id % 2 == 0:
            d = kwargs.copy()
            d['id'] = str(id + 1)

            return redirect(reverse(view, args=args, kwargs=d))

        return view(request, *args, **kwargs)
    return inner

@ensure_odd_id
def test(request, id):
    return HttpResponse('test {}'.format(id))

urlpatterns = [url(r'^test/(?P<id>\d+)/$', test)]

if __name__ == '__main__':
    settings.configure(DEBUG=True, ROOT_URLCONF='test')

    from django.core.management import execute_from_command_line
    execute_from_command_line()

如果您将此脚本保存为test.py 并使用python test.py runserver 运行它,您将看到请求/test/13 不会产生错误,但请求/test/18 会为调用reverse 产生NoReverseMatch 错误,而不是重定向到/test/19:

NoReverseMatch at /test/18/
Reverse for 'test.test' with arguments '()'
    and keyword arguments '{'id': '19'}' not found.
    0 pattern(s) tried: []

我感觉这与 view 函数是未修饰的 view 的事实有关,而 URL 解析器仅处理修饰的视图。

有没有什么好的方法可以重定向到已装饰的view 本身,而无需进行骇人的内省?

【问题讨论】:

    标签: python django redirect python-decorators


    【解决方案1】:

    Django实际上在reverse中使用了视图函数本身,所以我只需要传入装饰函数而不是原始视图:

    return redirect(reverse(inner, args=args, kwargs=d))
                            ^^^^^
    

    【讨论】:

      猜你喜欢
      • 2018-05-20
      • 1970-01-01
      • 2014-06-07
      • 1970-01-01
      • 2018-10-18
      • 2016-08-14
      • 2010-12-11
      • 1970-01-01
      • 2015-06-28
      相关资源
      最近更新 更多