#29750: Add a pre-dispatch() hook for class-based views
--------------------------------------------+------------------------
Reporter: François Freitag | Owner: nobody
Type: New feature | Status: new
Component: Generic views | Version: 2.1
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
--------------------------------------------+------------------------
Sharing Class-Based Views attributes across several view methods (`get()`,
`post()`) is often implemented by overriding the `dispatch()` method.
However, AFAICT subclasses cannot reuse attributes set by parent's
`dispatch()` method, because it immediately generates an `HttpResponse`.
Consider the following:
{{{#!python
class UsernameStartsWithAMixin:
def dispatch(self, request, *args, **kwargs):
# some logic
self.access_a = request.user.username.startswith('a')
return super().dispatch(request, *args, **kwargs)
class LongUsernameMixin:
def dispatch(self, request, *args, **kwargs):
# some logic
self.access_long = len(request.user.username) > 50
return super().dispatch(request, *args, **kwargs)
class MyView(UsernameStartsWithAMixin, LongUsernameMixin, View):
def dispatch(self, request, *args, **kwargs):
# Cannot make decisions based on self.access_a nor
self.access_long,
# because they are not set yet. Calling super() generates the
# HttpResponse.
return super().dispatch(request, *args, **kwargs)
}}}
Not being able to read attributes set by parent classes in `dispatch()`
results in code duplication, because some logic has to be repeated in each
view method.
For example, Django's
[https://github.com/django/django/blob/32fbccab406b680bc0a0a8d39a9b95c3a08bbc5a/django/views/generic/edit.py#L188-L194
BaseUpdateView] duplicates `self.object = self.get_object()` in the
`get()` and `post()` methods.
A possible addition to the framework would be a hook called in
`dispatch()`, responsible for initializing data shared by the class view
methods. For example, `BaseUpdateView` would be implemented as:
{{{#!python
class BaseUpdateView(ModelFormMixin, ProcessFormView):
def initialize(self):
super().initialize()
self.object = self.get_object()
}}}
Maybe `initialize` would be clearer as `pre_dispatch` or `initial`?
--
Ticket URL: <https://code.djangoproject.com/ticket/29750>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/058.e724785fc75919fdab12d63bf5e21444%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.