Demystifying mixins with Django

Ana Balica @anabalica slides - http://www.slideshare.net/AnaBalica/djangocon2015-demystifying-mixins-with-django

  • mixins controlled way to add to your classes
  • NOT a special python construct - just ordinary python class
  • inherit from object
  • single responsibility
  • not meant to be extended to another Mixin
  • not meant to be instantiated
  • implemented using multiple inheritance - order matters (method resolution order)

Say copy/paste a feature between classes that are otherwise different

class MyMixin(object):
    def mymethod(self):
        pass

class Foo(BaseFoo, MyMixin):
    # read as MyMixin is the base class, extended by BaseFoo, extended by Foo
    # so this is bad
    pass

class Foo(MyMixin, BaseFoo):
    # better
    pass

extensions goes from right to left

Class Based Views example

class LoginRequiredMixin(object):
    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated():
            raise PermissionDenied
        return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)

class AboutView(LoginRequiredMixin, TemplateView):
    template_name = "about.html"
  • alternative - TemplateView <- LoginRequiredTemplateView <- AboutView
  • but then DetailView needs LoginRequiredDetailView, UpdateView ... - duplicated code
  • so Mixin approach reduces duplication

Useful methods in class based views

  • dispatch() - check permissions
  • get_context_data() - add more data to the context
  • get_template_names() - more flexible selection of template

How to learn

Summary

  • single responsibility
  • plug-in functionality
  • isn’t creating a subtyping relation (so not SOLID, breaks Liskov)

Previous topic

What it’s really like building RESTful APIs with Django

Next topic

Coding with knives (part 2)

This Page