2016-11-27 62 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

已編輯的問題。現在可能更清楚了。 –