Opened 5 years ago

Closed 7 months ago

#13409 closed New feature (invalid)

"wrap" argument for django.conf.urls.defaults.url to decorate views more easily

Reported by: yourcelf Owned by: nobody
Component: Core (URLs) Version: master
Severity: Normal Keywords: url, RegexURLResolver, RegexURLPattern, decorators
Cc: chazen@…, erob@…, Florian.Sening@… Triage Stage: Accepted
Has patch: yes Needs documentation: yes
Needs tests: yes Patch needs improvement: no
Easy pickings: no UI/UX: no


The documention for cacheing recommends a method for using cache decorators in the urlconf, which is a natural way to do page-based cacheing. However, most urlconfs of any complexity use string representations of views (and perhaps also the "prefix" feature of patterns()). To decorate the views, one would have to import them all explicitly and then apply the wrapper functions, which is cumbersome.

The attached patch addresses this by adding a "wrap" function to url(), which specifies a function or list of functions with which to "decorate" the view. For includes, the wrap argument applies to all included URLs. It can be used like this:

urlpatterns = patterns('myapp.views',
    url(r'^pattern/$', 'viewfunc', wrap=mydecorator),
    url(r'^pattern2/$', include('otherapp.urls'), wrap=[mydecorator1, mydecorator2]),

This can provide a natural way to add cacheing or any other decoration (such as login_required) both to individual views, or to all the views within an include.

Attachments (2)

wrap_kwarg_for_url.diff (4.6 KB) - added by yourcelf 5 years ago.
New feature: wrap kwarg for "url" to decorate views.
wrap_kwarg_for_url.patch (4.8 KB) - added by Semmel 4 years ago.
New feature: wrap kwarg for "url" to decorate views. (usable with trunk)

Download all attachments as: .zip

Change History (11)

Changed 5 years ago by yourcelf

New feature: wrap kwarg for "url" to decorate views.

comment:1 Changed 5 years ago by Alex

  • Needs documentation set
  • Needs tests set
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Design decision needed

comment:2 Changed 5 years ago by erob

hm, what is the advantage of using a wrap keyword argument? i don't see any, at first glance,
especially when include is being used. worse, it seems not explicit to define a wrap, but rather
somewhat implicit.. i'd stick with standard decorators and not add any more overhead in url routing

comment:3 Changed 5 years ago by erob

  • Cc erob@… added

comment:4 Changed 5 years ago by yourcelf

Two advantages:

  1. You can use it even when you define the view function as a string. Basically, this is a side effect of Django already having some magic to resolve strings into view functions. Django has this magic, presumably, for two reasons -- so you can reduce typing by including a prefix in your patterns() call when all the view functions are from the same module, and to make it unnecessary to explicitly import all the different views you might reference in a urlconf, which might become cumbersome.
  1. You can apply a decorator to all of the views in an "include". Thus, you can apply the decorators (things like cacheing and login_required) to URLs defined in a reusable app, or for whole portions of an application or site. This reduces duplication of your decorators, and allows decorating the functionality of other people's code that you may not want to have to modify.

As the Django documentation I linked to in the summary indicates, the URLconf can be a natural place to include decorators for things like cacheing, and allows you to avoid coupling cacheing with your view definition. However, if you define views in patterns() using strings, you can't decorate them. I would argue the URLconf is also a natural place to include decorators for things like logon_required as well, especially in the context of reusable apps whose URLconf I might want to include, but which I don't want to have to modify.

This will help keep "site" oriented notions like cacheing and permissions distinct from "app" oriented view logic, and to help keep definitions of these things DRY.

comment:5 Changed 5 years ago by julien

  • Severity set to Normal
  • Type set to New feature

Changed 4 years ago by Semmel

New feature: wrap kwarg for "url" to decorate views. (usable with trunk)

comment:6 Changed 4 years ago by Semmel

  • Cc Florian.Sening@… added
  • Easy pickings unset
  • UI/UX unset

I'm not sure if a wrap argument is the way to go but there really needs to be an easy way to do this.

Currently I'm using Marty Alchin's CurrentUserMiddleware as a decorator - effectively applying it to the whole admin. His original approach was to use a small lambda wrapper function. Since was replaced by a different approach is needed.

Btw: I just added a version of the original patch that works with trunk.

comment:7 Changed 3 years ago by aaugustin

  • Component changed from Core (Other) to Core (URLs)

comment:8 Changed 3 years ago by aaugustin

  • Triage Stage changed from Design decision needed to Accepted

Another use case is to apply the atomic decorator to a group of views.

I think the concept is useful, but I'm not convinced by the proposed API. url() lines are often long and wrap would be buried at the end.

I'd like to see an API more targeted towards groups of URLs, ie. something at the level of patterns or include rather than at the level of url.

Using strings rather than the view objects themselves in URLconfs is annoying, because it delays errors and complicates debugging. I don't mind if the API doesn't improve this use case. Importing the view explicitly and wrapping in in a decorator is a better idea.

comment:9 Changed 7 months ago by bpeschier

  • Resolution set to invalid
  • Status changed from new to closed

patterns and dotted string urls are now deprecated, which invalidates the main focus of the ticket as described.

Though I can see the use case of wrapping groups of urls as aaugustin described, pushing view functionality (decorators) through include which just builds up the urlconf strikes me as inappropriate (what about includes inside the included urlconf for example?).

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