在新创建实例的保存方法上访问 m2m 关系
Access m2m relationships on the save method of a newly created instance
我想(仅)在创建 Order 实例时发送电子邮件。在电子邮件模板中,我需要访问 m2m 关系。不幸的是,似乎 m2m 关系尚未填充,itemmembership_set.all() 方法 returns 是一个空列表。
这是我的代码:
class Item(models.Model):
...
class Order(models.Model):
...
items = models.ManyToManyField(Item, through='ItemMembership')
def save(self, *args, **kwargs):
pk = self.pk
super(Order, self).save(*args, **kwargs)
# If the instance is beeing created, sends an email with the order
# details.
if not pk:
self.send_details_email()
def send_details_email(self):
assert len(self.itemmembership_set.all()) != 0
class ItemMembership(models.Model):
order = models.ForeignKey(Order)
item = models.ForeignKey(Item)
quantity = models.PositiveSmallIntegerField(default=1)
一些评论建议使用信号。虽然您可以使用信号,特别是 m2m_changed
信号,但只要您修改 m2m 字段,它就会始终触发。据我所知,发件人模型(在您的示例中,即 ItemMembership
)无法知道关联的 Order
实例是否刚刚创建。
当然,您可以使用 cache
框架在调用 Order
对象的 save()
时设置一个临时标志,然后在 m2m_changed
结束时发出信号并删除标志。缺点是你必须验证这个过程,它打败了使用信号来解耦东西的目的。
我的建议是从您的模型中完全删除所有这些电子邮件发送功能。相反,将其实现为辅助函数,然后在成功创建 Order
对象及其关联的 ItemMembership
对象后显式调用辅助函数。恕我直言,它也使调试变得容易得多。
我想(仅)在创建 Order 实例时发送电子邮件。在电子邮件模板中,我需要访问 m2m 关系。不幸的是,似乎 m2m 关系尚未填充,itemmembership_set.all() 方法 returns 是一个空列表。
这是我的代码:
class Item(models.Model):
...
class Order(models.Model):
...
items = models.ManyToManyField(Item, through='ItemMembership')
def save(self, *args, **kwargs):
pk = self.pk
super(Order, self).save(*args, **kwargs)
# If the instance is beeing created, sends an email with the order
# details.
if not pk:
self.send_details_email()
def send_details_email(self):
assert len(self.itemmembership_set.all()) != 0
class ItemMembership(models.Model):
order = models.ForeignKey(Order)
item = models.ForeignKey(Item)
quantity = models.PositiveSmallIntegerField(default=1)
一些评论建议使用信号。虽然您可以使用信号,特别是 m2m_changed
信号,但只要您修改 m2m 字段,它就会始终触发。据我所知,发件人模型(在您的示例中,即 ItemMembership
)无法知道关联的 Order
实例是否刚刚创建。
当然,您可以使用 cache
框架在调用 Order
对象的 save()
时设置一个临时标志,然后在 m2m_changed
结束时发出信号并删除标志。缺点是你必须验证这个过程,它打败了使用信号来解耦东西的目的。
我的建议是从您的模型中完全删除所有这些电子邮件发送功能。相反,将其实现为辅助函数,然后在成功创建 Order
对象及其关联的 ItemMembership
对象后显式调用辅助函数。恕我直言,它也使调试变得容易得多。