【发布时间】: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