在Django中,当一个子节点保存在一个外键关系中时,我该如何通知父节点?

wgx48brx  于 2023-06-25  发布在  Go
关注(0)|答案(3)|浏览(125)

我有以下两个模型:

class Activity(models.Model):
    name = models.CharField(max_length=50, help_text='Some help.')
    entity = models.ForeignKey(CancellationEntity)
    ...

class Cancellation(models.Model):
    activity = models.ForeignKey(Activity)
    date = models.DateField(default=datetime.now().date())
    description = models.CharField(max_length=250)
    ...

我希望Activity模型在保存与之相关的Cancellation(插入或更新)时能够知道。
最好的办法是什么?

wb1gzix0

wb1gzix01#

您要查看的是Django's signals(也可以查看this page),具体来说就是模型信号--更具体地说,是post_保存信号。信号是Django的插件/钩子系统版本。post_保存信号在每次保存模型时发送,无论是更新还是创建(它会让您知道它是否已创建)。这就是当一个活动取消时,你如何使用信号来得到通知

from django.db.models.signals import post_save

class Activity(models.Model):
    name = models.CharField(max_length=50, help_text='Some help.')
    entity = models.ForeignKey(CancellationEntity)

    @classmethod
    def cancellation_occurred (sender, instance, created, raw):
        # grab the current instance of Activity
        self = instance.activity_set.all()[0]
        # do something
    ...

class Cancellation(models.Model):
    activity = models.ForeignKey(Activity)
    date = models.DateField(default=datetime.now().date())
    description = models.CharField(max_length=250)
    ...

post_save.connect(Activity.cancellation_occurred, sender=Cancellation)
wlp8pajw

wlp8pajw2#

以下内容有什么问题?

class Cancellation( models.Model ):
    blah
    blah
    def save( self, **kw ):
        for a in self.activity_set.all():
            a.somethingChanged( self )
        super( Cancellation, self ).save( **kw )

它将允许您非常精确地控制模型之间的通知。在某种程度上,这是典型的“为什么面向对象这么好?“问题。我认为OO是好的,正是因为你的集合Cancellation和Activity对象可以充分合作。

ztmd8pv5

ztmd8pv53#

在Django中,你可以使用signal来更新父节点。为此,您需要创建一个信号来侦听子模型的post_save信号,并发送一个信号来更新父模型。

# models.py

from django.db import models
from django.dispatch import receiver
from django.db.models.signals import post_save

class Activity(models.Model):
    name = models.CharField(max_length=50, help_text='Some help.')
    entity = models.ForeignKey(CancellationEntity)

class Cancellation(models.Model):
    activity = models.ForeignKey(Activity)
    date = models.DateField(default=datetime.now().date())
    description = models.CharField(max_length=250)

@receiver(post_save, sender=Cancellation)
def update_activity(sender, instance, **kwargs):
    activity= instance.activity
    activity.save()

在上面的代码中,我们创建了一个信号函数来监听Cancellation模型的post_save信号。update_activity函数接受senderinstance参数,其中sender是发送信号的模型的类,instance是保存的模型的示例。kwargs参数包含任何其他关键字参数。
保存Cancellation对象时,sender参数设置为Cancellationinstance参数设置为已保存的Cancellation示例。update_activity函数获取activity对象并保存它,如果有,则触发它的post_save信号。
现在,当保存Cancellation对象时,update_activity函数也会更新Activity模型。

相关问题