Opened 12 years ago

Closed 11 years ago

#3717 closed (fixed)

{% url %} for generic views "object_list" and "object_detail"

Reported by: Ivan Sagalaev <Maniac@…> Owned by: Jacob
Component: Generic views Version: master
Severity: Keywords: generic views url reverse
Cc: Maniac@…, django@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


Short summary:

Implement template tags and infrastructure to create links in templates for objects and object lists being served by generic views. Template tags take the form:

{% obj_url "appname.ModelName" id %}
{% obj_list_url "appname.ModelName" %}

Full summary:

Change History (3)

comment:1 Changed 12 years ago by Simon G. <dev@…>

Component: UncategorizedGeneric views
Triage Stage: UnreviewedAccepted

Ivan's full proposal is (for those of us who like it all on one page):


I was lazily thinking about making {% url %} and "reverse" to work for
generic views ("GV"). The main problem why reversing doesn't work for GV
is that it relies on view's name to be unique while GVs obviously have
the same name for many URLs (that makes them "generic"). Hence a
signature of a GV consists not only of its name but also of some (but
not all) parameters from info_dict.

## A common case

I've failed to invent a good general way of dealing with this and
decided to go for 80 from 80/20 rule. It looks like in most cases people
need reversing for GVs pointing to object pages: "object_list" and
"object_detail". May be also for date based GVs but let's leave them
aside for a while.

So for "object_list" and "object_detail" I propose this syntax:

     {% obj_url "appname.ModelName" id %}
     {% obj_list_url "appname.ModelName" %}

Both GVs have their own tag that knows the actual name of a GV (like
"django.views.generic.list_detail.object_list"). Though I like it this
way it's not set in stone and may be some parameter would be better
(like {% url "object_detail" "appname.ModelName" %}).

Tags accept a model name as a first argument. This will require a
special version of "reverse" that checks for a view name and for a model
name that it knows how to get from a "queryset" parameter from info_dict.

This looks to me both simple for a template tag and useful for most real

## More special case

There is one special case that I feel is not that special to not be
addresses. Sometimes you have to URLs that have the same GVs _and_
querysets against the same model:

     (r'/objects/$', object_list, {
       'queryset': Model.objects.all(),
     (r'/objects/active/$', object_list, {
       'queryset': Model.objects.filter(active=True),

The distinction by model name won't work here. For this I propose an
optional fourth member to an urlconf pattern: view's given name:

     (r'/objects/$', object_list, {
         'queryset': Model.objects.all(),
     (r'/objects/active/$', object_list, {
         'queryset': Model.objects.filter(active=True),

And the tag will accept it as a first parameter:

     {% obj_list_url "active_objects" %}

This will require additional configuration but I think it's okay since
it's not required for a common case and is simple enough.

This "view name" will also solve other problems: reversing for the rest
of GVs and may be a permalink decorator that James Bennett was talking
about in django-user recently.

<small>Now I think that this proposal is better sounds like "introduce
view names, use model's name for this in known generic views"</small>

comment:2 Changed 12 years ago by Florian Apolloner <florian@…>

Cc: django@… added

comment:3 Changed 11 years ago by Chris Beaven

Resolution: fixed
Status: newclosed

This has been fixed now we can have named URL patterns.

Note: See TracTickets for help on using tickets.
Back to Top