Mixins for Fun and Profit
Tags: programming, softwaredevelopment, python, django
Published: 2018-12-19 21:39:44

---
title: Mixins for Fun and Profit
published: true
tags: programming,software-development,python,django
canonical_url: https://easyaspython.com/mixins-for-fun-and-profit-cb9962760556
---

This post originally appeared on [Easy as Python](https://easyaspython.com/mixins-for-fun-and-profit-cb9962760556) in December 2016.

***

There are people out there who have the time, motivation, and resources to cook meals entirely from scratch. They'll turn flour, water, and eggs into pasta and turn cheese, cream, and spices into a sauce. These people make delicious food, but it takes time. Can you imagine how much longer it would take if they also milled the wheat, farmed the chickens, and milked the cows themselves?

When creating software, there's sometimes a limit to the depth we should go. When pieces of what we'd like to achieve have already been executed well by others, though, it makes a lot of sense to reuse them. Instead of milling wheat and raising cows, we can buy flour and butchered beef. We can start from scratch, but not _scratch_ scratch.

One way to set ourselves up for success in object-oriented programming is through a concept called a mixin. In Python, mixins are supported via [multiple inheritance](https://en.wikipedia.org/wiki/Multiple_inheritance). Mixins take various forms depending on the language, but at the end of the day they encapsulate behavior that can be reused in other classes.

The delineation between using true inheritance and using mixins is nuanced, but it comes down to the fact that a mixin is independent enough that it doesn't feel the same as a parent class. Mixins aren't generally used on their own, but aren't abstract classes either.

Suppose we've written a slew of Python software and our application is ready to launch. We're about to hit the button when someone comes over and says “what kinds of things are we logging?” _Dear God_, you think. _We aren't logging anything!_ We could go ahead and add the following boilerplate to all our modules to get started with logging:

```python
import logging

class EssentialFunctioner:
    def __init__(self):
        ...

        self.logger = logging.getLogger(
            '.'.join([
                self.__module__,
                self.__class__.__name__
            ])
        )

    def do_the_thing(self):
        try:
            ...
        except BadThing:
            self.logger.error('OH NOES')
```

That's not too bad, but imagine doing this to twenty or thirty classes. Not fun. How can mixins help? Have a look. Let's create a `LoggerMixin` that does the same work as above:

```python
import logging

class LoggerMixin:
    @property
    def logger(self):
        name = '.'.join([
            self.__module__,
            self.__class__.__name__
        ])
        return logging.getLogger(name)
```

With this nicely encapsulated, we can now go around adding the following to our existing code:

```python
class EssentialFunctioner(LoggerMixin):
    def do_the_thing(self):
        try:
            ...
        except BadThing:
            self.logger.error('OH NOES')

class BusinessLogicer(LoggerMixin):
    def __init__(self):
        self.logger.debug('Giving the logic the business...')
```

We wrote the functionality just once, but now we can use it everywhere! All we have to do is inherit from `LoggerMixin` and we can proceed using `self.logger` as if we'd set that up in `EssentialFunctioner` and `BusinessLogicer`! Pretty awesome.

There are certain places where heavy use of mixins can save a ton of time or cognitive load. A use case that came up recently was in a Django project where several class-based views needed to serve only traffic within our intranet. An existing middleware does this check, raising an `Http404` if a request comes from outside the network. Adding that functionality to our classes was fairly easy, using `decorator_from_middleware` and `method_decorator` on the views' `dispatch` methods:

```python
from django.utils.decorators import decorator_from_middleware, method_decorator
from django.views import generic

from app import middleware

network_protected = decorator_from_middleware(
    middleware.NetworkProtectionMiddleware
)

@method_decorator(network_protected, name='dispatch')
class SecretView(generic.View):
    ...
```

However, when I added a second piece of functionality I had to decorate those views too. I was getting a little tired of decorating.

![](https://cdn-images-1.medium.com/max/480/1*Pf-6CQy4ncyO-sxAtmVNTw.gif)<figcaption>Happy Holidays</figcaption>

Instead, I refactored the network protection integration into a mixin, allowing all our class-based views to inherit from this as they saw fit:

```python
from django.utils.decorators import decorator_from_middleware, method_decorator
from django.views import generic

network_protected = decorator_from_middleware(
    middleware.NetworkProtectionMiddleware
)

class NetworkProtectionMixin:
    @method_decorator(network_protected)
    def dispatch(self, *args, **kwargs):
        return super().dispatch(*args, **kwargs)

class SecretView(NetworkProtectionMixin, generic.View):
    ...
```

A similar approach can be used for Django's permissions, authentication, and more. This is powerful, and when used correctly can result in wonderfully expressive code. It also reduces complexity, allowing easier unit testing and comprehension.

At the end of the day, mixins are a DRY way to architect code, abstracting potentially complex functionality so that developers can concentrate more fully on the task at hand instead of propping up all the pieces. Rejoice!

Have you used mixins in practice? I'd love to hear more.

#### You may also enjoy [my other stories about building stuff in Django](https://easyaspython.com/django/home).

* * *