我收到错误“_reverse_with_prefix()参数在*必须是序列之后,而不是int”当我尝试反转时。我以前在视图中硬编码参数,但我试图使其动态化。有什么建议吗?
查看:
def add_review(request, product_id):
p = get_object_or_404(Product, pk=product_id)
if request.method == 'POST':
form = ReviewForm(request.POST)
if form.is_valid():
form.save()
#HARDCODED: return HttpResponseRedirect('/products/1/reviews/')
return HttpResponseRedirect(reverse('view_reviews', args=(p.id)))
else:
form = ReviewForm()
variables = RequestContext(request, {'form': form})
return render_to_response('reserve/templates/create_review.html', variables)
def view_reviews(request, product_id):
product = get_object_or_404(Product, pk=product_id)
reviews = Review.objects.filter(product_id=product_id)
return render_to_response('reserve/templates/view_reviews.html', {'product':product, 'reviews':reviews},
context_instance=RequestContext(request))
urlpatterns = patterns('reserve.views',
url(r'^clubs/$', 'index'),
url(r'^products/(?P<product_id>\d+)/reviews/$', 'view_reviews'),
url(r'^products/(?P<product_id>\d+)/add_review/$', 'add_review'),
url(r'^admin/', include(admin.site.urls)),
)
答案 0 :(得分:21)
检查args=(p.id)
内的reverse()
,必须是args=(p.id,)
。第一种形式被视为整数而不是序列。
一个特殊问题是构造包含0或1的元组 items:语法有一些额外的怪癖来容纳这些。空 元组是由一对空括号构成的;一个元组 通过使用逗号跟随值来构造一个项目(它不是 足以将一个值括在括号中。)
另外,请使用'reserve.views.view_reviews'
而不仅仅是'view_reviews'
,因此:
reverse('reserve.views.view_reviews', args=(p.id,))
答案 1 :(得分:1)
由于您的模式为变量指定了匹配项,因此它被视为关键字参数,因此您应该将调用调整为反向。
return HttpResponseRedirect(reverse('view_reviews', kwargs={'product_id':p.id})
答案 2 :(得分:0)
那是因为args需要元组,但是当你使用args =(p.id)时,实际上,python会认为是整数p.id,你可以看看源代码django 1.6如下:
def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None, current_app=None):
if urlconf is None:
urlconf = get_urlconf()
resolver = get_resolver(urlconf)
args = args or []
kwargs = kwargs or {}
if prefix is None:
prefix = get_script_prefix()
if not isinstance(viewname, six.string_types):
view = viewname
else:
parts = viewname.split(':')
parts.reverse()
view = parts[0]
path = parts[1:]
resolved_path = []
ns_pattern = ''
while path:
ns = path.pop()
# Lookup the name to see if it could be an app identifier
try:
app_list = resolver.app_dict[ns]
# Yes! Path part matches an app in the current Resolver
if current_app and current_app in app_list:
# If we are reversing for a particular app,
# use that namespace
ns = current_app
elif ns not in app_list:
# The name isn't shared by one of the instances
# (i.e., the default) so just pick the first instance
# as the default.
ns = app_list[0]
except KeyError:
pass
try:
extra, resolver = resolver.namespace_dict[ns]
resolved_path.append(ns)
ns_pattern = ns_pattern + extra
except KeyError as key:
if resolved_path:
raise NoReverseMatch(
"%s is not a registered namespace inside '%s'" %
(key, ':'.join(resolved_path)))
else:
raise NoReverseMatch("%s is not a registered namespace" %
key)
if ns_pattern:
resolver = get_ns_resolver(ns_pattern, resolver)
return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
看看这个iri_to_uri(resolver._reverse_with_prefix(view,prefix,* args,** kwargs)),它使用* args,所以你应该确保args是一个序列,
根据文档,带有一个项目的元组应该添加逗号来创建,你的代码应该是这样的:
return HttpResponseRedirect(reverse('view_reviews', args=(p.id,)))