Hi there, After refactoring the middlewares to new-style middlewares as we have them now, I am left with two pain points: * atomic requests are still special cased and not in a middleware * process_view is as useless as always (it can neither alter nor convert args/kwargs or the view) To change this I am proposing the following changes: * Deprecate request.urlconf and provide a way to set the urlconf __before__ the middleware chain is entered * Resolve view before the middleware chain is entered This will imo improve existing code and allow for many new possibilities: 1.) Replace or transform kwargs/view. If the view is resolved before the middleware chain is entered, we can set resolver_match immediatelly effectively making process_view useless: class MyMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): view, args, kwargs = request.resolver_match # If you call view() directly here you can return a response and do what process_view could do: return view(request, args, kwargs) # ... or you could add a profiling decorator to the view without affecting the rest of the middlewares # process_view did not allow for this feature in the past (you couldn't alter the view, just call and return a response): request.resolver_match.func = profiler(request.resolver_match.func) return self.get_response(request) 2.) Rewrite atomic requests to a middleware again: class TransactionMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # Either as it is now by simply covering the view request.resolver_match.func = make_view_atomic(request.resolver_match.func) # ... or by actually covering the following middleware layers too: # This was not possible before because middlewares wouldn't have access to the view # Excemption would still be controlled by the view itself view, args, kwargs = request.resolver_match get_response = self.get_response non_atomic_requests = getattr(view, '_non_atomic_requests', set()) for db in connections.all(): if db.settings_dict['ATOMIC_REQUESTS'] and db.alias not in non_atomic_requests: get_response = transaction.atomic(using=db.alias)(view) return get_response(request) The only thing left is to provide a way to dynamically alter the URL conf; which we can do by adding a setting (yes a setting) which points to a callable with a default implementation of: def urlconf_factory(request): return settings.ROOT_URLCONF Before entering the middleware chain we'd then do urlconf = urlconf_factory(request) set_urlconf(urlconf) resolver = get_resolver(urlconf) request.resolver_match = resolver.resolve(request.path_info) request.urlconf = urlconf # if needed -- this would have the added benefit of allowing proper reversal of urls inside middlewares if needed (the correct urlconf is already set in the thread local) What do you think? Cheers, Florian
I'm not sure this part is feasible. It's an intentional part of
middleware design AFAIK (and useful) that middleware can modify
request.path and have this modification respected in view resolution.
--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/3f216c46-c48d-4ff1-bd6a-dcc2fb090c43%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.