如何在Django中实现Singleton

1zmg4dgp  于 2022-11-26  发布在  Go
关注(0)|答案(3)|浏览(171)

我有一个对象只需要示例化一次。尝试使用redis缓存示例失败,错误为cache.set("some_key", singles, timeout=60*60*24*30),但由于其他线程操作,出现序列化错误:
类型错误:无法pickle _thread.lock对象
但是,我可以根据需要轻松地缓存其他示例。
因此我在寻找一种创建Singleton对象的方法,我也尝试过:

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

在www.example.com中view.py我在Singleton.loadSingles()上调用,但我注意到我得到了
找到:0个单曲
在2-3个请求之后。请问在Djnago上创建Singleton而不使用第三方库的最好方法是什么,第三方库可能会尝试序列化和持久化对象(在我的情况下这是不可能的)

bf1o4zei

bf1o4zei1#

我发现使用唯一索引更容易实现这一点

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

    class Meta:
        abstract = True
h7wcgrx3

h7wcgrx32#

这是我的单例抽象模型。

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()
xzlaal3s

xzlaal3s3#

下面的代码只是阻止创建Revenue模型的新示例(如果存在的话)。我相信这应该会为您指明正确的方向。
祝你好运!

class RevenueWallet(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    class Meta:
        verbose_name = "Revenue"

    def save(self, *args, **kwargs):
        """
        :param args:
        :param kwargs:
        :return:

        """
        # Checking if pk exists so that updates can be saved
        if not RevenueWallet.objects.filter(pk=self.pk).exists() and RevenueWallet.objects.exists():
            raise ValidationError('There can be only one instance of this model')
        return super(RevenueWallet, self).save(*args, **kwargs)

相关问题