Question

Here is the question how do I use reverse for the generic view object_detail?

If I use it like the following, the error message will be: NoReverseMatch at /comment/add/ Reverse for '' with arguments '()' and keyword arguments '{}' not found.

in views.py:

urlresolvers.reverse('django.views.generic.list_detail.object_detail')
              return HttpResponseRedirect(resp)

in urls.py

common_info_dict = {
    'extra_context':{
         'blogtitle':"Thinking",
         'blogsubtitle':"- blog system",
         'articles_count':Entry.objects.count,
         'comments_count': 0,
         'visitors_count' : 0,
         'category_list':Category.objects.all,
         'tag_list':Tag.objects.all,
         'comment_form': CommentForm,
    },
}

object_detail_info_dict = {
    'queryset': Entry.objects.all(),
    'slug_field': 'slug',
    'template_object_name': 'post',
}

object_detail_info_dict.update(common_info_dict)

    urlpatterns += patterns('django.views.generic.list_detail',
       (r'^posts/(?P<slug>[-\w]+)/$', 'object_detail', object_detail_info_dict),
    )
Was it helpful?

Solution

The only way to use reverse with generic views - named urls config.

urlpatterns += patterns('django.views.generic.list_detail',
  (r'^posts/(?P<slug>[-\w]+)/$', 'object_detail',
                          object_detail_info_dict, 'post_detail'),
)

reverse('post_detail', args=('foobar',))

OTHER TIPS

This question seems to be for older versions of Django. I'm not familiar with how the old generic views work. But the new class-based generic views have the same problem.

Reversing doesn't work "out of the box" because View.as_view() returns a different wrapper function each time, and they don't compare equal to each other, so reverse() can't find the reverse route by comparing two functions that aren't equal.

There is another way, although it's non-standard. This is what I do for my class-based views:

class OrderView(LoginRequiredMixin, CreateView):
    model = Order
    form_class = OrderForm

OrderView.plain_view = staticmethod(OrderView.as_view())

In this case, I use plain_view to mean the view returned by as_view() with no arguments. If you pass arguments to as_view(), then the wrapper it returns will actually be different to the plain one. So if you need both, you'd have to assign them to different properties:

OrderView.plain_view = staticmethod(OrderView.as_view())
OrderView.bonk_view = staticmethod(OrderView.as_view(whee='bonk'))

You can link to these view attributes in urls.py:

urlpatterns = patterns('',
    url(r'^order/$', views.OrderView.plain_view),
    url(r'^frob/$', views.OrderView.bonk_view),

and then you can reverse them by reversing the view attributes:

def get_success_url(self):
    return reverse(OrderView.plain_view)

def get_failure_url(self):
    return reverse(OrderView.bonk_view)

I found the best solution, use reverse_lazy():

https://docs.djangoproject.com/en/1.5/ref/urlresolvers/#reverse-lazy

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top