Как добиться ассоциативного права в django? - PullRequest
0 голосов
/ 04 марта 2020

У меня есть три объекта для модели A, B, C A относится к B, а B относится к C Как мне достичь отношения от A к C в django?

class Product(models.Model):
name = models.CharField(max_length=30)
similar_product = models.ManyToManyField('self')

Предположим, я создаю объект A модели Product и другой объект B для той же модели. и для B я добавляю A в качестве аналогичного продукта. Это также создаст отношения B -> A и A -> B. Теперь я добавляю еще один продукт с именем C, и его аналогичный продукт называется A., поскольку A относится к B, я хочу также назначить B как аналогичный продукт для C. (Закон де Моргана)

Как я могу достичь этого?

Ответы [ 2 ]

2 голосов
/ 04 марта 2020

Я предполагаю, что ваша модель выглядит следующим образом:

class C(models.Model):
    #some fields

class B(models.Model):
    c = models.ForeignKey(C)

class A(models.Model):
    b = models.ForeignKey(B)

Если у вас есть объект, вы можете легко получить доступ от a.b.c до c.

По запросам вы можете использовать __ оператор:

A.objects.filter(b__c=#your c object)
0 голосов
/ 04 марта 2020

Итак, давайте предположим, что у вас есть данный Product и вы хотите проверить , является ли другой данный Product похожим на первый:

class Product(models.Model):
    similar_products = models.ManyToManyField('self')
    def is_similar(self, other):
        if other in self.similar_products.all():
            return True
        else:
            # recursively call is_similar()
            return any(similar.is_similar(other) for similar in self.similar_products.all())

Это не требует добавления отношений при их создании. Так что теперь вы можете сделать a.is_similar(b), чтобы проверить, связаны ли a и b, и это вернет True, если a <=> c <=> d <=> b.

Если вы предпочитаете явно добавлять все отношения при создании <=> c, используйте обработчик сигнала для m2m_changed:

@receiver(m2m_changed, sender=Product):
def add_connections(sender, instance, action, **kwargs):
    # instance is a
    # pk_set contains the pk of c
    if action == 'post_add':
        for similar in instance.similar_products.all():
            # similar is b for example (existing relationship with a)
             similar.similar_products.add(Product.objects.filter(pk__in=pk_set))

Примечание: я изменил ваше поле similar_products на множественное, так как оно должно быть в м2м.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...