Share objects between django views / global objects

Viewed 300

Often in Django I want to create and configure some object at startup, and have it available everywhere. For example a third-party API client.

So when django starts I want to do this:

from some.thirdparty import ThirdPartyClient
from django.conf import settings
...
my_thirdparty_client = ThirdPartyClient(configstring=settings.SOME_CONFIG_ITEM)

And then in a view somewhere I want to do this:

from somewhere import my_thirdparty_client

def whatever(request):
    my_thirdparty_client.do_stuff()
    my_thirdparty_client.do_even_more_stuff()

Obviously I understand that I can instantiate the client at the start of the view, but if initalizing the instance is expensive I don't want to do it on every request.

What is the idiomatic Django way of creating these kinds of objects that I want to share between views?

1 Answers

What is the idiomatic Django way of creating these kinds of objects that I want to share between views?

Django has nothing to do with this problem.
You just need to use the design pattern which is called - Singleton

I prefer to use a metaclass to implement this pattern in Python
but there are other ways too.

class SingletonMetaclass(type):

    _instance = None

    def __call__(cls, *args, **kwargs):
        assert not (args or kwargs), 'Singleton should not accept arguments'

        if isinstance(cls._instance, cls):
            return cls._instance
        else:
            cls._instance = super(SingletonMetaclass, cls).__call__()
            return cls._instance


class ThirdPartyClient(metaclass=SingletonMetaclass):

    def __init__(self):
        self.configstring = settings.SOME_CONFIG_ITEM

In order to initialize your client, you could use AppConfig.ready method.
It will be run only once when your Django app is ready to be used.

Related