簡體   English   中英

Django連接臨時pre_save信號

[英]Django connect temporary pre_save signal

我已經為Django信號問題苦苦掙扎了幾天,請多多關照。

場景

我希望使用一個黑盒方法(實際上是geodjango中的LayerMapping加載器,但這在這里並不重要),該方法可以生成並保存模型實例。 由於某種原因,它無法設置模型中的字段之一。 不幸的是,該字段不能為null,因此黑盒方法失敗,並顯示IntegrityError。 示例代碼:

models.py

class MyModel(models.Model):
    field1 = models.IntegerField()
    field2 = models.IntegerField()
    field3 = models.IntegerField() # This one is the problem

call_black_box.py

from some_app import black_box
from models import MyModel

def call_it():
    black_box(MyModel, some_other_args) # Fails

黑匣子例程嘗試創建MyModel的某些實例,但將失敗,並顯示以下錯誤:IntegrityError:“ field3”列中的null值違反了非null約束

我的解決方案

我已經動態生成了一個pre_save回調,將其附加到MyModel上,然后在最后將其斷開連接(因為我不一定總是想要這種行為):

call_black_box.py

from some_app import black_box
from models import MyModel
from django.db.models.signals import pre_save

def call_it():
    def pre_save_callback(sender, instance, *args, **kwargs):
        instance.field3 = 1
    pre_save.connect(pre_save_callback, sender=MyModel)
    try:
        black_box(MyModel, some_other_args) # OK
    finally:
        pre_save.disconnect(pre_save_callback, sender=MyModel)

它有效,但是有更好的方法嗎? 我猜測如果與此功能同時執行其他一些操作,則可能會出錯。 對我來說這不是問題,因為我目前按順序進行所有操作,但並不理想嗎?

謝謝!

編輯

我沒有提供足夠的細節。 對於第二個功能,分配給field3的值將有所不同:

def call_it_differently():
    def pre_save_callback(sender, instance, *args, **kwargs):
        instance.field3 = some_other_value
    pre_save.connect(pre_save_callback, sender=MyModel)
    try:
        black_box(MyModel, some_other_args) # OK
    finally:
        pre_save.disconnect(pre_save_callback, sender=MyModel)

所以我不能提供默認值,也不能覆蓋save方法-因為這些選項僅允許我指定一個值,而我需要靈活地應用一個任意值。

如果我正確理解了您的問題,則可以為模型中的第三個字段定義默認值

class MyModel(models.Model):
    field1 = models.IntegerField()
    field2 = models.IntegerField()
    field3 = models.IntegerField(default=1) # This one is the problem

因此,如果未指定該值,則Django將默認值為1

Django信號通常用作掛鈎點。 假設您正在編寫將由其他人使用的第三方應用程序,並且想要向他們提供一些掛鈎點來操縱您的代碼,然后將使用信號。

在您的方案中,我寧願覆蓋Model的save()方法,也不願使用信號。

class MyModel(models.Model):
    field1 = models.IntegerField()
    ///
    field3 = models.IntegerField()

    def save(self, *args, **kwargs):
        self.field3 = 1
        super(MyModel, self).save(*args, **kwargs)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM