Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将“外来”对象添加到集合时运行代码_Python_Django_Python 3.x - Fatal编程技术网

Python 将“外来”对象添加到集合时运行代码

Python 将“外来”对象添加到集合时运行代码,python,django,python-3.x,Python,Django,Python 3.x,我在Django v3模型中有外键关系: class Example(models.Model): title = models.CharField(max_length=200) # this is irrelevant for the question here not_before = models.DateTimeField(auto_now_add=True) ... class ExampleItem(models.Model): myParent

我在Django v3模型中有外键关系:

class Example(models.Model):
    title = models.CharField(max_length=200)  # this is irrelevant for the question here
    not_before = models.DateTimeField(auto_now_add=True)
    ...

class ExampleItem(models.Model):
    myParent = models.ForeignKey(Example, on_delete=models.CASCADE)
    execution_date = models.DateTimeField(auto_now_add=True)
    ....
每当将ExampleItem添加到示例实例中的项目列表时,是否可以运行/触发代码?我想做的是运行一些检查,根据具体的示例实例,在保存ExampleItem之前可能会修改它

说明

假设示例的类not_before date规定ExampleItem的执行日期不得早于not_before,我想检查要保存的ExampleItem的执行日期是否违反此条件。如果是这样的话,我想更改执行日期以使其有效,或者抛出一个异常,以较容易的为准。对于重复的执行日期,也就是说,如果各个示例已经有一个具有相同执行日期的ExampleItem,则情况也是如此

因此,从某种角度来看,我有如下代码:

def doit(request, example_id):
    # get the relevant `Example` object
    example = get_object_or_404(Example, pk=example_id)
    # create a new `ExampleItem`
    itm = ExampleItem()
    # set the item's parent
    itm.myParent = example  # <- this should trigger my validation code!
    itm.save()              # <- (or this???)
问题是,这个视图不是创建新ExampleItems的唯一方法;例如,我还有一个API可以做同样的事情,更不用说用户可以通过REPL手动添加ExampleItems了。最好不要在所有可以创建新ExampleItems的地方重复验证代码

我在研究信号,特别是ExampleItem的pre_save和post_save,但我认为pre_save太早,post_save太迟。。。另外,m2m_的变化看起来很有趣,但我没有多对多的关系


处理这些要求的最佳/正确方法是什么?我想,它们似乎相当普遍。我必须重新构造我的模型吗?

这里最明显的解决方案是将此代码放在ExampleItem.save方法中-注意model.save不会被某些queryset批量操作调用

在您自己的应用程序模型上使用signals处理程序实际上是-signal的目标是允许您的应用程序连接到其他应用程序的生命周期,而无需更改其他应用程序的代码

同样不相关,但您可以通过其初始值设定项直接填充新创建的模型实例,即:

itm = ExampleItem(myParent=example)
itm.save()
您甚至可以直接保存它们:

# creates a new instance, populate it AND save it
itm = ExampleItem.objects.create(myParent=example)

这仍然会调用模型的save方法,因此对您的用例来说是安全的。

可能您可以利用模型之间的onetoone关系,并在使用模型表单时使用您自己的自定义验证器。查找信号。示例可以侦听ExampleItem预保存信号。不要问我细节,我只知道这些!我明白其中的道理。但是,快速测试表明,视图中后跟itm.save的itm.myParent=example不会触发example的save。我遗漏了什么吗?当然不会触发Example.save。我说过会吗???我的建议是将验证代码放在ExampleItem.save中。该项可以访问其父示例实例。然后,您可以将验证代码直接放在ExampleItem.save中,也可以将其放在某个Example.validate\u itemself中,item方法并从ExampleItem.save调用self.myParent.validate\u itemself。很抱歉,不知何故,我误读了您的答案,意味着您建议覆盖Example的save。例如,这样做当然更有意义,到目前为止效果很好。