2012-06-25 22 views
5

"_reverse_with_prefix() argümanı" tersine çevirmeyi denediğimde "int değil, bir sıra olmalıdır" hatası alıyorum. Daha önce parametreyi görünümde kodladım ama dinamik hale getirmeye çalışıyorum. Herhangi bir tavsiye?HttpResponseRedirect nasıl doğru şekilde yapılır?

Görünüm: reverse()

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

Ayrıca daha önce buna sahip için kullanılan yönlendirme kısayol https://docs.djangoproject.com/en/dev/topics/http/shortcuts/#redirect – super9

cevap

17

Kontrol args=(p.id), bu args=(p.id,) olmalıdır. İlk form, bir sıra yerine tamsayı olarak ele alınır.

Refs the doc ve the tutorial:

A special problem is the construction of tuples containing 0 or 1 items: the syntax has some extra quirks to accommodate these. Empty tuples are constructed by an empty pair of parentheses; a tuple with one item is constructed by following a value with a comma (it is not sufficient to enclose a single value in parentheses).

Ayrıca böylece yerine sadece 'view_reviews' ait 'reserve.views.view_reviews' kullanın:

reverse('reserve.views.view_reviews', args=(p.id,)) 

Kontrol the doc of reverse

+0

bakın. Args = (p.id,) olarak değiştirdiğimde hatayı alıyorum: 'view_reviews' için '(1,)' argümanları 've' {} 'argümanları ile tersine çevrildi. – sharataka

+0

@sharataka güncellemeyi kontrol edin, ayrıca [url model adını] kullanabilirsiniz (https://docs.djangoproject.com/en/dev/topics/http/urls/#id2) – okm

1

senin desen bir değişkene bir maç atar olduğundan, Bir anahtar kelime argümanı olarak kabul edilir, böylece aramayı tersine çevirmeniz gerekir. tamsayı p.id args başlığın gerekir, ancak args = (p.id) kullandığınızda, aslında, piton düşünüyorum çünkü var

return HttpResponseRedirect(reverse('view_reviews', kwargs={'product_id':p.id})

+0

Bu değişikliği yaptım ve hata "NoReverseMatch at/products/1/add_review /: 'view_reviews' için argümanlar 'ile tersine'() 've anahtar kelime argümanları' {'product_id': 1} 'bulunamadı. Bu, garip bir sürümü kullandığımda garip çünkü 1 değeriyle bir product_id dosyasıdır. Ayrıca, "add_review" için hatanın neden yapılmadığından emin değilim ... view_reviews'a yönlendirilmemeli mi? – sharataka

+0

Bu aslında önemli değil. – okm

0

, sen kaynak kodu olarak 1,6 django bakabilirsiniz izleyin:

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)) 

göz göre bu iri_to_uri (resolver._reverse_with_prefix (görünüm, önek, * args, ** kwargs)) Eğer args sağlamalıdır yüzden, bu bir dizisidir, * args kullanın

Dokümanlar, bir öğe ile tuple oluşturmak için virgül eklemek gerekir, kod thi olmalıdır s:

return HttpResponseRedirect(reverse('view_reviews', args=(p.id,))) 
İlgili konular