Django连接临时pre_save信号

时间:2014-03-11 11:44:45

标签: python django django-models django-signals

我几天来一直在努力解决Django信号问题而感谢你的想法。

方案

我希望使用黑盒子方法(它实际上是geodjango中的LayerMapping加载器,但这并不重要)生成并保存模型实例。出于某种原因,它无法在我的模型中设置其中一个字段。不幸的是,该字段不能为空,因此黑盒方法因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”列中的空值违反非空约束

我的解决方案

我已经动态生成了一个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方法 - 因为这些选项只允许我指定一个值,而我需要灵活地应用任意一个。

1 个答案:

答案 0 :(得分:1)

如果我正确理解了您的问题,您可以为模型中的第三个字段定义默认值

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

因此,如果未指定该值,则Django将默认值为1