为啥使用 filter() 给出了我想要的,但使用 get() 会引发错误

Posted

技术标签:

【中文标题】为啥使用 filter() 给出了我想要的,但使用 get() 会引发错误【英文标题】:Why using filter() gives what I want, but with get() raises an error为什么使用 filter() 给出了我想要的,但使用 get() 会引发错误 【发布时间】:2020-12-12 03:56:32 【问题描述】:

我创建了 cusom QuerySet 和 Manager 来序列化我的数据。

class UpdateQuerySet(models.QuerySet):
    def serialize(self):
        return serialize("json", self)

class UpdateManager(models.Manager):
    def get_queryset(self):
        return UpdateQuerySet(self.model, using=self._db)

class Update(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    objects = UpdateManager()

然后,当我试图获取这些数据时,它使用了这个:

json_data = Update.objects.filter(id=1).serialize()

但会引发 AttributeError('Update' 对象没有属性 'serialize'):

json_data = Update.objects.get(id=1).serialize()

【问题讨论】:

因为.filter 返回querysetget 返回object .serializeUpdateQuerySet 对象上的函数,.filter() 返回这样的QuerySet,而.get() 只是一个简单的对象。 【参考方案1】:

您还想将serialize 添加到UpdateManager

class UpdateManager(models.Manager):
    def get_queryset(self):
        return UpdateQuerySet(self.model, using=self._db)

    def serialize(self):
        return self.get_queryset().serialize()

【讨论】:

【参考方案2】:

您的Update.objects.filter(id=1) 返回一个UpdateQueryset,而QuerySet 提供了一个.serialize(…) 方法。 .get(id=1) 函数将返回一个Update 模型对象,因此不是QuerySet,并且默认情况下模型提供.serialize(…) 方法。

但是,您可以自己实现它,甚至可以泛化 QuerySet 以使用各种模型,例如:

class SerializableQuerySet(models.QuerySet):
    def serialize(self):
        return serialize('json', self)

class SerializableManager(models.Manager):
    _queryset_class = SerializableQuerySet

    def serialize(self, *args, **kwargs):
        return self.get_queryset().serialize(*args, **kwargs)

class SerializableModel(models.Model):
    objects = SerializableManager()
    
    def serialize(self):
        return serialize('json', [self])

    class Meta:
        abstract = True

class Update(SerializableModel):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

所以现在所有从SerializableModel 继承的模型,例如Update,现在都将使用SerializableManager,并且还将继承.serialize() 方法,这样您也可以使用Update.objects.get(pk=1).serialize(),例如.

【讨论】:

以上是关于为啥使用 filter() 给出了我想要的,但使用 get() 会引发错误的主要内容,如果未能解决你的问题,请参考以下文章

XAMPP apache服务器没有使用我想要的端口,不知道为啥

为啥 sympy 在整合部分功率时给出不同/错误的答案?

Guava:为啥没有 Lists.filter() 函数?

为啥 JSLint 会在这个函数上给出严格的违规错误?

为啥我的CSS中blur滤镜无法使用?

梯度下降和正规方程没有给出相同的结果,为啥?