Opened 7 years ago

Closed 21 months ago

#13409 closed New feature (invalid)

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

Reported by: Charlie DeTar 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

Description

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 Charlie DeTar 7 years ago.
New feature: wrap kwarg for "url" to decorate views.
wrap_kwarg_for_url.patch (4.8 KB) - added by Florian Sening 5 years ago.
New feature: wrap kwarg for "url" to decorate views. (usable with trunk)

Download all attachments as: .zip

Change History (11)

Changed 7 years ago by Charlie DeTar

Attachment: wrap_kwarg_for_url.diff added

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

comment:1 Changed 7 years ago by Alex Gaynor

Needs documentation: set
Needs tests: set
Triage Stage: UnreviewedDesign decision needed

comment:2 Changed 7 years ago by Etienne Robillard

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
hooks...

comment:3 Changed 7 years ago by Etienne Robillard

Cc: erob@… added

comment:4 Changed 7 years ago by Charlie DeTar

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 6 years ago by Julien Phalip

Severity: Normal
Type: New feature

Changed 5 years ago by Florian Sening

Attachment: wrap_kwarg_for_url.patch added

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

comment:6 Changed 5 years ago by Florian Sening

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 admin.site.root was replaced by admin.site.urls a different approach is needed.

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

comment:7 Changed 4 years ago by Aymeric Augustin

Component: Core (Other)Core (URLs)

comment:8 Changed 4 years ago by Aymeric Augustin

Triage Stage: Design decision neededAccepted

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 21 months ago by Bas Peschier

Resolution: invalid
Status: newclosed

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