我正在尝试使用中间件在 Django rotue 中捕获丢失的变量 - 但是我无法反转 URL,因为 Django 找不到视图(即使它存在于 urlconf 中)。例如:
使用这条路线:
# matches /test and /game/test
url(r'^((?P<game>[A-Za-z0-9]+)/)?test', 'hyp.views.test'),
我正在尝试检测是否未给出游戏部分,并在这种情况下使用中间件重定向:
class GameMiddleware:
def process_view(self, request, view_func, view_args, view_kwargs):
if 'game' in view_kwargs:
game = view_kwargs['game']
if game is None:
# As a test, attempt to resolve the url
# Correctly finds ResolverMatch for hyp.views.test, game=TestGame
print resolve('/TestGame/test', urlconf=request.urlconf)
# Fails with "Reverse for 'hyp.views.test' with arguments '()'
# and keyword arguments '{'game': 'TestGame'}' not found."
return HttpResponseRedirect(reverse(
request.resolver_match.url_name, # 'hyp.views.test'
urlconf=request.urlconf,
kwargs={'game': 'TestGame'}
))
return None
request.urlconf
确实包含测试网址:
{ '__name__': 'urlconf', '__doc__': None, 'urlpatterns': [
<RegexURLPattern None ^$>,
<RegexURLPattern None ^((?P<game>[A-Za-z0-9]+)/)?test>
], '__package__': None }
我唯一能想到的是 URL 重写器可能无法处理包含可选部分的正则表达式 - 更好的解决方案是为这些情况创建单独的视图(我将有很多视图可选game
参数)或者我可以修复它吗?
更新
我设法通过删除路线中的包装括号来使其工作(因此它读取r'^(?P<game>[A-Za-z0-9]+/)?test'
并通过'TestGame /'作为游戏传递 - 但这并不理想,因为我game.rstrip('/')
每次都必须调用(尽管仅在中间件中) . 也很难使用标签作为以预期{% url %}
结尾的名称。/
如果有人有更好的解决方案,请保持打开状态。