Заставьте Django возвращать связанные объекты

Я пытаюсь отфильтровать одну таблицу и получить связанные строки из другой таблицы в виде вложенного объекта.

Модели следующие:

class KpiArea(models.Model):
    harvest = models.CharField(max_length=45)
    area_id = models.IntegerField()
    percentage = models.FloatField(max_length=10)
    class Meta:
        managed = False
        db_table = 'kpi_area'
        unique_together = ['harvest', 'area_id']
        
class KpiAreaProducts(models.Model):
    product = models.CharField(max_length=45)
    percentage = models.FloatField(max_length=10)
    area_id = models.IntegerField()
    harvest = models.ForeignKey(KpiArea, on_delete=models.PROTECT, db_column = "harvest")  
    class Meta:
        managed = False
        db_table = "kpi_area_products"
        unique_together = ['harvest', 'area_id']

Моей целью было бы иметь возможность получать связанные объекты всякий раз, когда я фильтрую KpiArea, в идеале как свойство, содержащее массив связанных объектов. Что-то вроде этого:

[
    {
        area_id : 1, 
        harvest: '2020/2021', 
        percentage: 25, 
        products: [
            {
                product: 'soy',
                percentage: 15,
                area_id : 1
            },
            {
                product: 'wheat',
                percentage: 35,
                area_id : 1
            },
        ]
    }    
]
  

Я пробовал связывать с 2 правящими ключами в модели KpiAreaProducts, и unique_together (согласно другим вопросам SO), чтобы достичь этого.

Может кто-нибудь направить меня в нужном направлении?

Вы можете использовать prefetch_related...[Django-doc] с Prefetch...[Django-doc] вот так:

from django.db.models import Prefetch


kpi_areas = KpiArea.objects.prefetch_related(
    Prefetch(
        "kpiareaproducts_set",
        queryset=KpiAreaProducts.objects.only("product", "percentage", "area_id"),
        to_attr="products",
    )
)

for area in kpi_areas:
    for product in area.products:
        print(product)
Вернуться на верх