我认为处理您想要的两种行为的最佳方法不是使用信号,而是使用through
表上覆盖的 save() 和 delete() 方法,您将使用参数明确定义,through
请参见:https://docs.djangoproject .com/en/dev/ref/models/fields/#django.db.models.ManyToManyField.through。这:https ://docs.djangoproject.com/en/dev/topics/db/models/#overriding-predefined-model-methods
像这样的东西:
# -*- coding: utf-8 -*-
from django.db import models
class Item(models.Model):
# fields
# ...
class Collection(models.Model):
items = models.ManyToManyField(Item, related_name="collections", through="CollectionItem")
# other fields
# ...
class CollectionItem(models.Model):
collection = models.ForeignKey(Collection)
item = models.ForeignKey(Item)
def save(self, *args, **kwargs):
# Only allow this relationship to be created on some_condition
# Part 1 of your question.
if some_condition:
super(CollectionItem, self).save(*args, **kwargs)
# Update some fields on Collection when this
# relationship is created
# Part 2 of your question (1/2)
self.Collection.updateSomeFields()
def delete(self, *args, **kwargs):
collection = self.collection
super(CollectionItem, self).delete(*args, **kwargs)
# Update some fields on Collection when this relationship
# is destroyed.
# Part 2 of your question (2/2)
collection.updateSomeFields()
顺便说一句,您会发现添加关系会在此直通模型上引起保存信号。
而且,关于信号,一旦你有了直通表,你就可以收听 pre_save 和/或 post_save 信号,但它们都不允许你直接否决关系的创建。
如果您的一个或两个模型是由第 3 方提供的,并且您确实无法创建直通表,那么,是的,信号路径可能是唯一的方法。
https://docs.djangoproject.com/en/dev/ref/signals/#m2m-changed
在这种情况下,您可以侦听 m2m_changed 事件并触发对您的集合对象的更新(您的问题的第 2 部分)并追溯删除不当创建的关系(您的问题的第 1 部分)。但是,由于后一点很笨拙,如果可以的话,我会坚持使用显式直通表。