[英]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.