如何从多对多关系中的相关模型中提取数据?

How to pull data from a related model in a many-to-many relationship?

所以,我有两个应用程序,我想 link 在我的项目中以多对多的关系在一起。

第一个应用程序由以下模型描述。

model.py:

class ChannelCategory(models.Model):
    name = models.CharField(max_length=200, db_index=True)
    def __str__(self):
        return '%s' % self.name

class Channel(models.Model):
    category = models.ForeignKey(ChannelCategory, on_delete=models.CASCADE)
    name = models.CharField(max_length=200, db_index=True)

    class Meta:
        ordering = ['category']

    def __str__(self):
        return '%s (%s)' % (self.category, self.name)

第二个应用程序由以下模型描述

class Tariff(models.Model):
    channels_list = models.ManyToManyField(Channel, blank=True, db_index=True, symmetrical=False)

def __str__(self):
     return '%s' % self.name

def get_channels_categories(self):
    return ([str(p.category) for p in self.channels_list.all()])

def get_channels_objects(self):
    return ([str(p.name) for p in self.channels_list.all()])

现在我想做什么?假设关税对象包含[=36​​=]4个渠道,其中有不同类别,我们得到大致如下图:关税A有来自 2 个不同频道类别 的 4 个频道,例如,“mega”资费

['ChannelCategory_1: Channel_1', 'ChannelCategory_1: Channel_3', 'ChannelCategory_2: Channel_2', 'ChannelCategory_2: Channel_4']

我不明白如何在界面上正确显示信息。我需要在我的模板上获取此类信息:

['ChannelCategory_1: 'Channel_1', 'Channel_3'']

['ChannelCategory_2: 'Channel_2', 'Channel_4'']

我很乐意提供任何帮助,在此先感谢!

已更新

为什么'QuerySet'对象在'channels_list'中没有属性?

tariff = Tariff.objects.prefetch_related('channels_list')
category_channel_dict = defaultdict(list)
for channel in tariff.channels_list.all():
     category_channel_dict[channel.category.name].append(channel.name)

此代码有效:

from collections import defaultdict

tariff = Tariff.objects.prefetch_related('channels_list').filter(id=1)
category_channel_dict = defaultdict(list)

for channel in tariff.channels_list.all():
    category_channel_dict[channel.category.name].append(channel.name)

OUTPUT:
{
    'category_1': ['Channel1', 'Channel2'],
    'category_2': ['Channel1', 'Channel2']
}

成功了。不知道好看不好看,但是在class Tariff里面,需要描述函数get_channels:

from itertools import groupby

def get_channels(self):
channels = list(str(p).split(':') for p in self.channels_list.all())
channel_list = []
for category, name in groupby(channels, lambda x: x[0]):
    channels_list_by_group = ";".join([channel[1] for channel in name])
    channels_list_by_category = (category + ":" + channels_list_by_group + ".")
    print(channels_list_by_category)
    channel_list.append(channels_list_by_category)
return ''.join(channel_list)

因此,我们将得到以下内容channel_list(此函数处理的从我的数据库中提取的示例):

ChannelCategory_1: ChannelName_1; ChannelName_2; ChannelName_3; ChannelName_4.

ChannelCategory_2: ChannelName_5; ChannelName_6.

ChannelCategory_3: ChannelName_6 etc.