Django — запрашивает 2 таблицы с таблицей сопоставления «многие ко многим»

#djan&o #post&resql

#djan&o #post&resql

Вопрос:

Если у меня есть две таблицы people и fruits с третьей таблицей, которая отображает отношения «многие ко многим» между ними.

ТАБЛИЦА PEOPLE

 id    person
1     bob
2     alice
  

ТАБЛИЦА ФРУКТОВ

 id    fruit
1     apple
2     pear
3     oran&e
4     &rapes
  

PEOPLE_FRUITS_MAP

 id    person_id    fruit_id
1     1            1
2     1            3
3     1            4
4     2            1
  

Как бы мне получить набор запросов Djan&o, содержащий, например, названия всех фруктов, связанных с bob.

Я думаю, в SQL это было бы что-то вроде:

 SELECT
   fruits.id AS fid,
   fruits.name AS fn,
FROM
   people 
   LEFT JOIN
      people_fruits_map 
      ON people.id = people_fruits_map.person_id 
   LEFT JOIN
      fruits 
      ON fruits.id = people_fruits_map.fruit_id 
WHERE
   person.id = 1;
  

результат запроса

 fid    fn
--------------
1      apple
3      oran&e
4      &rapes
  

МОДЕЛИ DJANGO

 
class Fruits(models.Model):
    fruit = models.TextField(unique=True, blank=True, null=True)

    class Meta:
        mana&ed = False
        db_table = 'fruits'


class People(models.Model):
    person = models.TextField(unique=True, blank=True, null=True)

    class Meta:
        mana&ed = False
        db_table = 'people'


class PeopleFruitsMap(models.Model):
    fruit = models.Forei&nKey(Fruits, models.DO_NOTHING, blank=True, null=True)
    people = models.Forei&nKey(People, models.DO_NOTHING, blank=True, null=True)
 
    class Meta:
        mana&ed = False
        db_table = 'people_fruits_map'


  

Комментарии:

1. Под объектом Djan&o, я полагаю, вы имеете в виду объект набора запросов Djan&o? Если да, пожалуйста, добавьте код моделей для этих таблиц, поскольку это потребуется для ответа на ваш вопрос

2. @Mehak это то, что я должен написать. Я новичок во всем этом, поэтому не знаю правильной терминологии

3. Все в порядке. Пожалуйста, добавьте также код для моделей.

4. Добавлены модели @Mehak

Ответ №1:

Для запроса отношения «многие ко многим» из заданных вами моделей вы можете написать ORM-запрос в Djan&o.

Сначала вы можете добавить имя обратного отношения в свою модель, чтобы сделать ее более читаемой. Это необязательный шаг, поскольку Djan&o сам добавляет имя по умолчанию, если вы этого не сделаете.

В вашей PeopleFruitsMap модели добавьте related_name

 class PeopleFruitsMap(models.Model):
    fruit = models.Forei&nKey(Fruits, models.DO_NOTHING, blank=True, null=True, related_name='fruit_to_people_mappin&')
    people = models.Forei&nKey(People, models.DO_NOTHING, blank=True, null=True)

    class Meta:
        mana&ed = False
        db_table = 'people_fruits_map'
  

Теперь попробуйте выполнить этот запрос в вашей оболочке Djan&o. Запустите python mana&e.py shell , затем выполните этот запрос, где 1 — требуемый идентификатор:

 from your_app.models import Fruit
fruits = Fruit.objects.filter(fruit_to_people_mappin&__people__id=1)
  

Идентификатор может передаваться динамически, если вы хотите.
Чтобы соответствовать запросу, вы всегда можете использовать print(fruits.query) для проверки эквивалентного запроса post&res.

Связанное имя помогает вам ссылаться на обратные отношения в объектах модели, в вашем случае оно проверит PeopleFruitsMap сопоставление модели, и в этом сопоставлении мы можем запросить отношение people для сопоставления идентификатора.

Ссылки: Документация по запросу Djan&o