Can dependency injection be used with django?

I am very popular with using the technique of dependency injection to decouple my code. This would typically involve providing an object with functionality, into the constructor of it's dependent.

For the first time, I am using django to make a web api (with a database of objects attached). I intended to inject an elaborate dependency into the otherwise simple method. (in my case it was functionality to interpret messages coming from RabbitMQ exchanges, but my minimal example is just interpreting a generic message as a site-dependent dictionary).

However in django everything seems to be autogenerated from either static methods or the definition of classes, I couldn't find where anything was actually instantiated or customisable to push the dependency in.

Is the technique and the django framework just incompatible or am I missing something?

Code so far

(minimal example recreation, not actual code)

in urs.py:

urlpatterns = [
    path("run/", views.run),
]

in views.py

def run(request):
    interpreter = AbstractDataInterpreter() #This is the object I want to inject
    data = interpreter.interpret(request)
    return JsonResponse(data, safe=False)

I have a test class TestDataInterpreter to use for testing.

I have a class CustomDataInterpreter custom for my domain/ecosystem.

I plan for for other interpreters on different deployments going forward.

But I can't find the mechanism to actually inject an interpreter into the run command on the different deployments.

In Python you can write a "class" which is intended to be inherited by other classes, which is useless on its own. You will find such classes described as "Mixin" classes in the Django Class-based view documentation. The essential rule (to avoid multiple-inheritance induced insanity) is that Mixin classes should inherit from object and are always inherited to the left of the class they are being mixed into. See below.

Also in Python, it's trivially easy to dynamically construct a class, using the three-argument form of the type function. So a static declaration such as

class MyView( LoginRequiredMixin, ListView):
    pass

might be dynamically created as

MyView = type( 'MyView',             # __name__ of the class,
    (LoginRequiredMixin, ListView),  # classes it inherits from, ordered
    {}                               # __dict__ (added class vars and methods)
)

I have to admit to not being entirely certain about "dependency injection", but hopefully you can use this to get the code pattern you desire in a Pythonic manner?

Back to Top