2016-11-27 42 views
0

我正在寻找一种可靠的方式来确保对于给定的Django模型实例,一个特定的字段只写入一次。确保django模型字段只写入一次?原子性保证没有锁

代码应该在使用芹菜甚至rq的视图或任务中运行。

我想用下面的代码片段:

from django.db import transaction 
from django.utils.timezone import now 

... 

def perform_writeonce(object_pk): 
    with transaction.atomic(): 
     instance = MyModel.objects.get(pk=object_pk) 

     if instance.value is None: 
      instance.value = 'Value written now : {}'.format(now()) 
      instance.save() 

的目标是价值应该只写一次且仅当它的值是无。

你对这段代码有信心吗?还是有我错过的东西?

我使用多个gunicorn实例和芹菜工作者与一个postgresql数据库服务器。

我试图避免不惜一切代价锁定,所以任何带有应用程序锁的解决方案都不好。

感谢您的任何帮助。

+0

我有信心。因为事务依赖于db层而不是应用层。 – itzMEonTV

回答

0

我在寻找一种可靠的方法来确保对于任何给定的django模型实例,只写一次特定的字段。

预期行为与datefields的auto_now_add选项类似。

auto_now_add不确保字段只写入一次。如果您真的想要,您仍然可以写入该字段。它只是没有在管理形式等默认显示

您可以通过设置Field.editable https://docs.djangoproject.com/en/1.10/ref/models/fields/#editable

Field.editable

如果False做同样的其他领域,字段将不会显示在管理员或任何其他 ModelForm。在模型验证过程中它们也被跳过。默认为 True

+0

对不起,我不清楚,我不想复制auto_now_add的行为和可编辑的属性。该问题与使用事务的并发和并发访问数据库相关联。无论如何谢谢 –

+0

然后,你应该对你的问题中的预期行为给予一个清晰的解释。如果您只想写入一次字段,那么该时间应该是实例首次保存到数据库时的时间。如果并发是一个问题,那么模型代码可能不是解决问题的合适位置。为什么不使用任务队列并让芹菜对这个特定的模型进行所有更新? –

+0

已编辑的问题。现在可能更清楚了。 –