Ограничения полей ManyToMany в Django - PullRequest
0 голосов
/ 08 октября 2019

Это общий вопрос базы данных, который не относится только к Django. Поскольку я использую Django, я спрашиваю об этом в этом контексте. Предположим, у меня есть три модели:

class ModelA(models.Model)
    name = models.CharField(max_length=255)

class ModelB(models.Model)
    a = models.ForeignKey(ModelA, on_delete=models.CASCADE)

class ModelC(models.Model)
    a = models.ForeignKey(ModelA, on_delete=models.CASCADE)
    bs = models.ManyToManyField(ModelB, blank=True)

Я бы хотел, чтобы ModelC имел ссылку на многие ModelB с. Я хотел бы, чтобы было ограничение, которое позволяет ModelC иметь ModelB, если они имеют общий ModelA. Есть ли способ правильно спроектировать это на уровне базы данных или это должно быть сделано логически в других частях системы?

Ответы [ 2 ]

1 голос
/ 08 октября 2019

Я не думаю, что есть способ применить это на уровне базы данных, но чтобы применить его в коде приложения, вы можете использовать сигнал m2m_changed (https://docs.djangoproject.com/en/2.2/ref/signals/#m2m-changed), чтобы выполнить эту проверку перед добавлениемчто-нибудь в ваших отношениях «многие ко многим».

0 голосов
/ 11 октября 2019

Спасибо Ross Mechanic, я решил это, используя этот метод. Для кого-то еще с таким же вопросом я решил его следующим образом:

def bs_changed(**kwargs):
    """
    :param kwargs:
    :return:
    """
    if kwargs['action'] != 'pre_add':
        return

    if kwargs['reverse']:
        b = kwargs['instance']
        cs = kwargs['model'].objects.filter(id__in=kwargs['pk_set'])
        for c in cs:
            if b.a != c.a:
                kwargs['pk_set'].remove(c.id)
    else:
        c = kwargs['instance']
        bs = kwargs['model'].objects.filter(id__in=kwargs['pk_set'])
        for b in bs:
            if b.a != c.a:
                kwargs['pk_set'].remove(b.id)


m2m_changed.connect(bs_changed, sender=ModelC.members.through)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...