Django多对多关系插入控件

2023-11-26

我有以下型号:

class Item(models.Model):
    # fields
    # ...

class Collection(models.Model):
    items = models.ManyToManyField(Item, related_name="collections")
    # other fields
    # ...

现在我想要两件事:

  1. 我想控制是否Item可以添加到Collection.
  2. 我想要Collection更新它的一些字段,如果Item被添加或删除。

对于第二个问题,我知道有django.db.models.signals.m2m_changed我可以用它来挂钩关系的变化。是否允许/可以更改Collection在信号回调中?我可以使用该信号来“中止”问题 1 的插入吗?


我认为实现您想要的两种行为的最佳方法不是使用信号,而是使用覆盖的 save() 和 delete() 方法through您将使用参数显式定义的表through see: 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()

顺便说一下,你会发现添加关系will通过模型对此产生保存信号。

而且,关于信号,一旦您有了 through 表,您就可以侦听 pre_save 和/或 post_save 信号,但它们都不允许您直接否决关系的创建。

如果您的一个或两个模型由第三方提供,并且您确实无法创建直通表,那么,是的,信号路由可能是唯一的方法。

https://docs.djangoproject.com/en/dev/ref/signals/#m2m-changed

在这种情况下,您可以侦听 m2m_changed 事件并触发对集合对象的更新(问题的第 2 部分),并追溯删除不适当创建的关系(问题的第 1 部分)。然而,由于后一点是非常混乱的,所以如果可以的话,我会坚持使用显式的直通表。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django多对多关系插入控件 的相关文章

随机推荐