python - Django F() 对象和自定义保存怪异

标签 python django django-models

我一直在使用 Django F() 对象来更新我的模型,以避免竞争条件。

我的模型还有一个自定义保存方法(我希望叛军的范围从 0 到 100)。

这里是一些示例代码:

class World(models.Model):
    ...
    world.rebels = models.IntegerField(default=0)
    ...

    def save(self, *args, **kwargs):
        ...
        if self.rebels > 100:
            self.rebels = 100
        elif self.rebels < 0:
            self.rebels = 0  
        ...
        super(World, self).save(*args, **kwargs)

现在我有一个函数可以将数量添加到叛军计数中。

world = World.objects.get(worldid=1)
rebchange = 0

print world.rebels
>>> 0

world.rebels = F('rebels') + rebchange

print world.rebels
>>> (+: (DEFAULT: ), 0)

world.save()

print world.rebels
>>> 100

多么奇怪,对吧?增量的值完全错误!然后,我用涉及 self.rebels 的条件注释掉了自定义保存方法,瞧,模型然后将正确的值保存到数据库中。 显然 (+: (DEFAULT: ), 0) > 100 在某种程度上是 True,并且触发了对 100 的更改。

我已将自定义保存方法更改为:

def save(self, fsave=False, *args, **kwargs):
    if fsave == False:
        ...
        if self.rebels > 100:
            self.rebels = 100
        elif self.rebels < 0:
            self.rebels = 0  
        ...
    super(World, self).save(*args, **kwargs)

然后在我的函数中,我调用 world.save() 两次:

world = World.objects.get(worldid=1)
rebchange = 0
world.rebels = F('rebels') + rebchange
world.save(fsave=True)
world.save()

print world.rebels
>>> 0

为了能够在保存 F() 对象时避免我的自定义保存,然后使用正确的值强制执行我的自定义保存。

这是预期的行为吗?如果是,是否有更简单的方法来完成我想要做的事情?

最佳答案

在 Python 中比较不同类型时,数字始终排在其他对象之前。因此,100 始终低于 F() 对象。

您确实需要为此进行特殊情况测试;您可以改为测试 self.rebels 是否是 F 的实例:

def save(self, *args, **kwargs):
    ...
    if not isinstance(self.rebels, F):
        if self.rebels > 100:
            self.rebels = 100
        elif self.rebels < 0:
            self.rebels = 0  
    ...
    super(World, self).save(*args, **kwargs)

Python 2 这样做是为了支持混合类型的排序列表,同时保证稳定的排序顺序。

由于此行为可能会导致微妙的意外错误(与您的情况完全相同),因此 Python 3 中已删除此行为,并且仅支持显式支持比较的类型。

关于python - Django F() 对象和自定义保存怪异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22200450/

相关文章:

python - 使用 Python 创建 Flash 动画的方法是什么?

django - 使用 Django 启动和停止定期后台任务

python - 如何JSON序列化Django模型的__dict__?

mysql - 加速 Django 查询 "latest"ForeignKey 相关对象

django - ** 之后的 _filter_or_exclude() 参数必须是映射,而不是 ReverseManyRelatedObjectsDescriptor

python - 为什么 Django-rest-swagger 找不到我的 api 路径?

python - 相当于 tf.depth_to_space 的 keras 模型

python - 在 Ubuntu 上通过 virtualenv 中的设置工具安装 Numpy 时出错

python - 如何使用我从网站上抓取的 json 填充我的 django 数据库

django - model.AutoField - form.save() 创建新记录(INSERT)而不是更新现有记录