Django: Как фильтровать данные с отношением «многие ко многим» - PullRequest
0 голосов
/ 09 января 2020

Предположим, у меня есть такие модели:

models.py

class Category(models.Model):
    name = models.CharField(max_length=70, verbose_name='Name')
    order_num = models.IntegerField(verbose_name='Order Number')

class Advertisement_Type(models.Model):
    name = models.CharField(max_length=70, verbose_name='Name')
    ad_category = models.ManyToManyField(Category, verbose_name='Ad Category')

class Advertisement(models.Model):
    title = models.CharField(max_length=70, verbose_name='Title')    
    ad_type = models.ForeignKey(Advertisement_Type, on_delete=models.CASCADE, verbose_name='Advertisement Type')

Как получить рекламу по категории и рекламе введите в таком формате, используя только фильтры? Возможно ли это? Потому что я могу думать только о том, чтобы запросить все, а затем вручную построить словарь / JSON через несколько циклов for и if-else, которых я бы хотел избежать.

Ожидаемый формат / вывод

advertisement_type: {
    name: 'Type 1',
    category: {'Health', 'Engineering'},
    advertisement: {ads1, ads2, ads3}, # Can these be objects?
},
advertisement_type: {
    name: 'Type 2',
    category: {'Math', 'Numbers'},
    advertisement: {ads4, ads5, ads6}, # Can these be objects?
}

Спасибо!

1 Ответ

0 голосов
/ 09 января 2020

Чтобы получить связанные объекты модели, вы можете использовать prefetch_related , который может работать с ManyToMany отношениями.

В примере ads_types, ad_category, advertisement_set являются QuerySets, поэтому они возвращают список объектов и также могут быть отфильтрованы.

ads_types = Advertisement_Type.objects.prefetch_related('ad_category', 'advertisement_set')

res = []
for adt in ads_type:
  res.append({
    "name": adt.name,
    "category": adt.ad_category.values_list('name', flat=True),
    "advertisement": adt.advertisement_set.values_list('title', flat=True),
  })

Или вы можете проверить Django Rest Framework сериализаторы для связанных объектов для получения json представления объекта вместе с отношениями.

Вы также можете улучшить поле ManyToMany, добавив параметр related_name .

...