Django连接临时pre_save信号 [英] Django connect temporary pre_save signal

查看:342
本文介绍了Django连接临时pre_save信号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



场景

p>

我希望使用一个黑盒方法(实际上是geodjango中的LayerMapping加载器,但这并不重要),用于生成和保存模型实例。由于某种原因,它无法设置我的模型中的一个字段。不幸的是,该字段不能为空,因此黑盒方法失败,并带有IntegrityError。示例代码:



models.py

  class MyModel(models。模型):
field1 = models.IntegerField()
field2 = models.IntegerField()
field3 = models.IntegerField()#这一个是问题

call_black_box.py

  from some_app从模型导入导入black_box 
MyModel

def call_it():
black_box(MyModel,some_other_args)#失败

黑盒子例程尝试创建一些MyModel实例,但会失败并显示错误:IntegrityError:列field3中的空值违反了非空约束



我的解决方案



我已经动态生成了pre_save回调,将其附加到MyModel,然后将其断开连接(因为我不一定总是想要这个行为):



call_black_box.py

  from some_app import black_box 
从模型导入MyModel
从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 ,例子,* 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)

所以我不能给出一个默认值,或者覆盖保存方法,因为这些选项只允许我指定一个值,而我需要灵活地应用一个值。

解决方案

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

  class MyModel(models.Model):
field1 = models.IntegerField()
field2 = models.IntegerField()
field3 = models.Integ erField(default = 1)#这是一个问题

所以如果没有指定值,那么Django将默认为1,


I've been struggling with a Django signal issue for a few days now and would appreciate your thoughts.

Scenario:

I wish to use a black box method (it's actually the LayerMapping loader in geodjango, but that's not important here) that generates and saves model instances. For some reason, it cannot set one of the fields in my model. Unfortunately, that field cannot be null, so the black box method fails with an IntegrityError. Example code:

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

The black box routine tries to create some instances of MyModel, but will fail with the error: IntegrityError: null value in column "field3" violates not-null constraint

My solution:

I have generated a pre_save callback dynamically, attached it to MyModel, then disconnected it at the end (because I don't necessarily always want this behaviour):

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)

It works, but is there a nicer way? I'm guessing this could go wrong if some other actions were executed at the same time as this function. Not a problem for me as I currently do everything sequentially, but not ideal?

Thanks!

edit:

I didn't give enough detail. The value assigned to field3 will be different for a second function:

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)

So I can't give a default value, or override the save method - because these options only allow me to specify a single value, whereas I need the flexibility to apply an arbitrary one.

解决方案

If I understood your question correctly, you can define the default value for the third field in your model

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

So if the value is not specified then Django will take 1 as default

这篇关于Django连接临时pre_save信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆