Soumaya
Soumaya

Reputation: 11

how to use a singleton instance in multiple django apps

I'm creating a website using django framework. I am using a singleton in one django application and I use it to store some variables . Now that I have created another app in my project, how can I import the data from my singleton to the new app.

class SingleInstanceMetaClass(type):
    def __init__(self, name, bases, dic):
        self.__single_instance = None
        super().__init__(name, bases, dic)

    def __call__(cls, *args, **kwargs):
        if cls.__single_instance:
            return cls.__single_instance
        single_obj = cls.__new__(cls)
        single_obj.__init__(*args, **kwargs)
        cls.__single_instance = single_obj
        return single_obj

class MyClass(metaclass=SingleInstanceMetaClass):
    def __init__(self):
        self.df = None
        self.del_var = None
        self.quali_col = None
        self.quanti_col = None
        self.target_var = None
        self.date_col = None

And this what my project looks like without the other django files(models,urls,...)

Project 
    Description
        -views.py
    Transformation
        -views.py 

Upvotes: 1

Views: 1849

Answers (1)

jsbueno
jsbueno

Reputation: 110301

First thngs first: there is no need for a metaclass for a singleton - just do this:

class MyClass(metaclass=SingleInstanceMetaClass):
    def __init__(self):
        self.df = None
        self.del_var = None
        self.quali_col = None
        self.quanti_col = None
        self.target_var = None
        self.date_col = None
    def __call__(self):
        return self

MyClass = MyClass()

This will create an instance, and through away the reference to the class: anyone trying to import or use MyClass will only get to the only instance ever created of it, no metaclass balckmagic needed for such a trivial thing.

Now, fow your question, the MyClass single instance will be avaliable to your project in the very same way any other named Python object is - just use a qualified import statment from your other app to get to it, like:

 from project.transformation.views import MyClass

Now, beware of one thing: in a production environment, django projects can have multiprocess workers - in that case you will have one separate instance for each worker. (if your production WSGI server is configured to use multi-threading only, you will get a single instance).

In that case, if you really want to share all the properties in "myclass" across all workers, you need a more sophisticated setup, combining properties and multiprocess data communication primitives like a multiprocessing.Value .
AND if your production setup will go for horizontal scaling, with process in different servers, that won't work as well - you will need to setup a key/value service like a redis instance to synchronise these properties across all workers.

Upvotes: 2

Related Questions