python - Django FloatField 和 DecimalField 创建返回与数据库中的对象不同
问题描述
我刚刚意识到,在 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 不返回带有 float 的对象,而是返回带有 int 的对象?
编辑:谢谢@Willem Van Onsem
如果您创建一个对象,则将传递给它们的对象的属性分配给它们(此处为 30)。而如果您获取数据,这些字段将读取数据库响应的结果,并对其进行解释 (float30)
但我仍然认为,如果在创建时,Django 返回“解释数据”会更好。编辑:我想我错了:这太神奇了,python 不喜欢“魔法”。
解决方案
这是来自 django 的错误吗?为什么 django 不返回相同的对象?
没有。这不是错误。如果你.create(..)
是一个对象,你首先构造一个Model
对象,然后调用.save()
. 但这因此意味着这些字段采用您给它们的值。30
默认情况下是 an int
,这意味着如果您查询type(a.price)
,您会得到:
>>> type(a.price)
<class 'int'>
如果您查询数据库,例如使用Model.objects.get(price=30)
,您将构建一个查询,例如这里的查询将如下所示:
SELECT *
FROM project_price
WHERE price = 30
数据库将通过一系列记录进行响应。这些记录由 Django ORM解释,不同的字段将构造 Python 对应项。For a将因此通过方法 [GitHub]FloatField
将包含数据库响应的“字符串”转换为 a 。float
to_python
现在在 Python 中 afloat
和int
是两种不同的类型,但这并不意味着两个这样的对象不能等价,例如:
>>> float(30) == int(30)
True
但是如果我们将它们转换为字符串,那么它们都会产生不同的字符串:
>>> str(int(30))
'30'
>>> str(float(30))
'30.0'
推荐阅读
- ruby - Ruby:在方法上下文中获取对 self 是其属性的对象的引用
- algorithm - 对问题的直觉?
- android - Android Wear 应用因桥接通知而被拒绝
- javascript - webapp网络:上传文件和修改
- javascript - 当用户使用 jQuery 滚动时,使用多个 div 触发滚动事件
- image - 如何在flutter中检索sqlite数据库中的图像数据?
- c# - 从代码窗口添加控件事件方法下拉总是到底部,这个可以改变吗
- javascript - 尝试使用 koa bodyparser 和 ctx.body 未定义
- python - TypeError 试图在 Dask 中连接列表
- paypal - 如何在 PayPal Express Checkout 中动态更改货币和传递其他数据