Opened 3 years ago

Closed 3 years ago

Last modified 2 years ago

#22203 closed Uncategorized (wontfix)

Automatically get default value for "current_app", for easier namespace support.

Reported by: Tai Lee Owned by: nobody
Component: Core (URLs) Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


Right now it seems that for a generic app to support the possibility of being installed in a URLconf with a namespace, the app author will need to take care to explicitly define a current_app for every call to reverse(), TemplateResponse, RequestContext, Context and {% url %}.

Django already adds a ResolverMatch object to every request. Shouldn't Django just use this to get a default value for "current_app", whenever users don't explicitly define one?

This should make it almost a non-issue to define the current app for every case except explicit calls to reverse(), Context and templates that are rendered without a RequestContext object (as none of these have access to the request).

We could even get a sensible default in those cases as well by storing the current app in thread local storage, and using that as a default in reverse().

Any objections, or any reason why Django doesn't already or can't do this?

Change History (3)

comment:1 Changed 3 years ago by Aymeric Augustin

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset

If you're talking about thread local storage, that really means global state (otherwise you would have no reason to make it thread local). We've always been at war with global state :-)

However, I agree that the URL namespacing API isn't optimal. I suspect #21927 would address your goals. Is this ticket a duplicate?

comment:2 Changed 3 years ago by Aymeric Augustin

Resolution: wontfix
Status: newclosed

In fact, I'm going to reject the idea to use global state for this purpose. I don't believe that's the answer.

That said, if you can build consensus on the DevelopersMailingList that there's no better answer, please reopen.

comment:3 Changed 2 years ago by Tai Lee

Does "per thread" (per request/response cycle) count as "global" state? Django already uses threading.local() in a number of places such as urlresolvers._prefixes, urlresolvers._urlconfs, CacheHandler._caches, ConnectionHandler._connections, trans_real._active, timezone._active.

The most notably similar use case is probably for timezone support, which allows users to call activate() to tell Django what timezone they are in, and then other parts of the code call get_current_timezone() to get the value stored in thread local storage.

I think it would be along the same lines to have the ability to set a current app and have other parts of the code get the current app, without having to pass an object around as an argument every step of the way, which is practically impossible.

For example, models with a get_absolute_url method (or perhaps multiple get_foo_url methods) that are rendered in templates. These functions can't take arguments when rendered as context variables in a template, and have no way to obtain the current namespace from the request object.

This would make it super easy for users (via middleware) or Django itself to inspect the request.resolver_match object and set the current app early in the request/response cycle, and then reverse() and {% url %} would just work without generic app authors having to explicitly build in support for multiple instances of their app being deployed within a single project.

Does anyone else think this would be a good idea, or does anyone have an alternative suggestion?

Last edited 2 years ago by Tai Lee (previous) (diff)
Note: See TracTickets for help on using tickets.
Back to Top