﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
29750	Add a pre-dispatch() hook for class-based views	François Freitag	François Freitag	"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`?"	New feature	closed	Generic views	dev	Normal	fixed		jon.dufresne@…	Ready for checkin	1	0	0	0	0	0
