Django HTTPResponseRedirect和Reverse可选参数

5
如何在Django中使用带有可选参数info的Reverse函数?我一直收到以下错误信息:
views.py:
def cartForm(request, prod):
    if request.method=="POST":
        quantity = request.POST.get('quantity', False)
        if quantity:
            add_to_cart(request, prod, quantity)
            return HttpResponseRedirect(reverse("cart"))
        #if no quantity indicated, display error message
        return HttpResponseRedirect(reverse('products.views.info', kwargs={'prod': prod, 'error':True}))

def info(request, prod, error=False):
    prod = Product.objects.get(id=prod)
    return render(request, "products/info.html", dict(product = prod, error=error))

urls.py:

url(r'^(?P<prod>\d+)/', "products.views.info", name='info'),

我一直遇到以下错误:
Reverse for 'products.views.info' with arguments '()' and keyword arguments '{'prod': u'2', 'error': True}' not found. 1 pattern(s) tried: ['products/(?P<prod>\\d+)/']

你确定你的URL没有重复吗?匹配错误显示的模式与你的urls.py片段不同。 - Burhan Khalid
1
@BurhanKhalid: Django允许在部分URL下包含URL模式;该模式包含在“'products/'”下。 - Martijn Pieters
可能是Django使用reverse()重定向到依赖于查询字符串的URL的重复问题。 - Martijn Pieters
@MartijnPieters 我的意思是这个模式是 (?P\d+)(但后来我编辑了帖子,因为它实际上给出了正确的错误信息);然后我意识到当这个模式只映射到一个关键字时,实际上会传入 两个 关键字;所以我的问题仍然存在。 - Burhan Khalid
1
@BurhanKhalid: 这就是问题的核心所在; OP希望在这里使用error参数做什么?没有提到其他URL模式。 - Martijn Pieters
4个回答

5
您可以使用以下方式传递可选的GET参数:
reverse('products.views.info', kwargs={'prod': prod})+'?error=true&some_other_var=abc'

reverse 返回解析后的URL字符串,因此您可以将任意数量的GET参数连接起来。


对于其他使用这段代码的人,以下是一些代码 - return HttpResponseRedirect('%s?%s' % (reverse('url-name', args=(args_in_url_pattern, )), '&'.join(['%s=%s' % (key, value) for key, value in request.GET.items()]))) - 也许应该进行URL转义处理? - Chris

3

这个链接已经失效。 - oruchkin
请尝试访问 https://docs.djangoproject.com/en/4.0/ref/contrib/messages/。 - Andrei

2

0

在视图函数中添加一个参数并不会将其转换为URL模式,在您的情况下,您已经直接将参数添加到了视图方法中,但没有将其映射到URL。

因此,当您尝试反向查找URL时,找不到具有error的模式,这就是为什么您会收到错误信息的原因。

您有两个选择:

  1. 制作可选模式,但我不建议这样做。

  2. 将相同的视图映射到多个URL,其中可选项首先匹配模式的顺序:

    url(r'^(?P<prod>\d+)/(?P<error>\d+)/', "products.views.info", name='info-error'),
    url(r'^(?P<prod>\d+)/', "products.views.info", name='info'),
    

现在,在您的视图中:

from django.shortcuts import redirect

def cartForm(request, prod):
    if request.method=="POST":
        quantity = request.POST.get('quantity', False)
        if quantity:
            add_to_cart(request, prod, quantity)
            return HttpResponseRedirect(reverse("cart"))
        #if no quantity indicated, display error message
        return redirect('info-error', prod=foo, error=True)

这里我正在使用redirect快捷方式


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接