我刚刚意识到,在Django2中,创建时的对象(使用xxx.objects.create或xxx.save)返回的对象与数据库中的实际对象(MODEL.objects)略有不同.get(创建的对象))。您可以使用DecimalField或FloatField看到它:
class Product(Model):
price = FloatField()
然后运行外壳程序(python manage.py shell):
from *project*.models import Product
a = Product.objects.create(price=30)
# or "a = Product(price=30); a.save()"
b = Product.objects.get(price=30)
a == b # True
str(a.price) == str(b.price) # False : "30" == "30.0"
这是Django的错误吗?为什么django不返回相同的对象?
因为使用xxx.objects.create方法创建对象时,您希望它返回与在数据库中搜索该对象时得到的对象相同的对象(至少具有相同的副本)。 我找到了create方法的源代码:
def create(self, **kwargs):
"""
Creates a new object with the given kwargs, saving it to the database
and returning the created object.
"""
obj = self.model(**kwargs)
self._for_write = True
obj.save(force_insert=True, using=self.db)
return obj
非常感谢!
编辑:我的问题是:为什么两个对象都不同?为什么在创建对象时,django不返回带浮点数的对象,而是带int的对象?
编辑:谢谢@Willem Van Onsem
如果创建对象,则为传递的对象分配属性 给他们(这里30)。而如果您获取数据,则这些字段将读取 数据库响应的结果,并对其进行解释(float30)
但是我仍然认为Django在创建时返回“解释数据”会更好。编辑:我想我错了:那太魔术了,而python不喜欢“魔术”。
答案 0 :(得分:0)
这是Django的错误吗?为什么django不返回相同的对象?
否。这不是错误。如果您.create(..)
对象,则首先构造一个Model
对象,然后调用.save()
。但这意味着字段将获得您赋予它们的价值。 30
默认为int
,因此,如果您查询type(a.price)
,则会得到:
>>> type(a.price)
<class 'int'>
例如,如果使用Model.objects.get(price=30)
查询数据库,则可以构造查询,例如,此处的查询将类似于:
SELECT *
FROM project_price
WHERE price = 30
数据库将通过一系列记录进行响应。这些记录由Django ORM 解释,并且不同的字段将构造Python副本。对于FloatField
,将通过to_python
method [GitHub]将包含数据库响应的“字符串”转换为float
。
现在在Python中,float
和int
是两种不同的类型,但这并不意味着两个这样的对象不能相等,例如:
>>> float(30) == int(30)
True
但是如果我们将它们转换为字符串,那么它们都会产生不同的字符串:
>>> str(int(30))
'30'
>>> str(float(30))
'30.0'