为啥使用 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
返回queryset
而get
返回object
?
.serialize
是UpdateQuerySet
对象上的函数,.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() 会引发错误的主要内容,如果未能解决你的问题,请参考以下文章