Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement Singleton in Django

I have an object that need to be instantiated ONLY ONCE. Tried using redis for caching the instance failed with error cache.set("some_key", singles, timeout=60*60*24*30) but got serialization error, due the other thread operations:

TypeError: can't pickle _thread.lock objects

But, I can comfortably cache others instances as need.

Thus I am looking for a way to create a Singleton object, I also tried:

class SingletonModel(models.Model):

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        # self.pk = 1
        super(SingletonModel, self).save(*args, **kwargs)
        # if self.can_cache:
        #     self.set_cache()

    def delete(self, *args, **kwargs):
        pass


class Singleton(SingletonModel):
    singles = []

    @classmethod
    def setSingles(cls, singles):
        cls.singles = singles


    @classmethod
    def loadSingles(cls):
        sins = cls.singles
        log.warning("*****Found: {} singles".format(len(sins)))

        if len(sins) == 0:
            sins = cls.doSomeLongOperation()
            cls.setSingles(sins)
        return sins

In the view.py I call on Singleton.loadSingles() but I notice that I get

Found: 0 singles

after 2-3 requests. Please what is the best way to create Singleton on Djnago without using third party library that might try serialising and persisting the object (which is NOT possible in my case)

like image 278
Paullo Avatar asked Jun 17 '26 18:06

Paullo


2 Answers

I found it easier to use a unique index to accomplish this

class SingletonModel(models.Model):
    _singleton = models.BooleanField(default=True, editable=False, unique=True)

    class Meta:
        abstract = True
like image 170
jpnauta Avatar answered Jun 20 '26 08:06

jpnauta


This is my Singleton Abstract Model.

class SingletonModel(models.Model):
    """Singleton Django Model"""

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        """
        Save object to the database. Removes all other entries if there
        are any.
        """
        self.__class__.objects.exclude(id=self.id).delete()
        super(SingletonModel, self).save(*args, **kwargs)

    @classmethod
    def load(cls):
        """
        Load object from the database. Failing that, create a new empty
        (default) instance of the object and return it (without saving it
        to the database).
        """

        try:
            return cls.objects.get()
        except cls.DoesNotExist:
            return cls()
like image 38
Ramkishore M Avatar answered Jun 20 '26 09:06

Ramkishore M