Search code examples
pythonpython-3.xdjangodjango-viewsabstract-class

Why some Django view classes had not been defined as abstract base class?


I'm writing a small and lightweight Django-like back-end framework for myself just for experiment.

If we look at ProcessFormView view(and some other views):

class ProcessFormView(View):
    def get(self, request, *args, **kwargs):
        return self.render_to_response(self.get_context_data())

    def post(self, request, *args, **kwargs):
        form = self.get_form()
        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

    ...

To me it sounds like a valid case to define this class as an "abstract base class".

After all, It needs that sub-classes provide render_to_response(), get_context_data(), get_form(), form_valid(), form_invalid(). (They will be provided by TemplateResponseMixin and FormMixin.)

I can do something like this:

class ProcessFormView(View, metaclass=ABCMeta):
    @abstractmethod
    def render_to_response(self, context):
        pass

    @abstractmethod
    def get_context_data(self):
        pass

    @abstractmethod
    def get_form(self):
        pass

    @abstractmethod
    def form_valid(self, form):
        pass

    @abstractmethod
    def form_invalid(self, form):
        pass

    def get(self, request, *args, **kwargs):
        return self.render_to_response(self.get_context_data())

    def post(self, request, *args, **kwargs):
        form = self.get_form()
        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

    ...

Or even better we can factor these abstract methods out to another ABC class and inherit from it to clear things up.

I know that of course it's a made decision and nothing is wrong with it. I mostly interested to know if do what I just showed, how can it cause problem in future? what would be the cons that I'm not aware of?

The only disadvantage that I can think about is I should then write many abstract classes! This make the code base much bigger.


Solution

  • Aside from the mentioned fact that the code base would become much bigger, I think I found the main reason.

    It's true that if we subclass ProcessFormView and "intend to use its get and post method", we have to eventually somehow provide those mentioned methods. But what if for some reason we only want to use its post method and provide our own custom method for get? (They are only get called inside post and get).

    This way we no longer have to implement the render_to_response and get_context_data() abstract method. Defining them as abstractmethods would unnecessarily force sub-classes to implement them.