How to implement Singleton in Django

2019-08-17 03:23发布

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)

1条回答
仙女界的扛把子
2楼-- · 2019-08-17 04:23

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()
查看更多
登录 后发表回答