如何对从查询集中多对多字段中提取的列表进行分组?

How can you group a list extracted from queryset many-to-many field?

我有一个描述电视频道本质的模型:

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

如果我调用关税对象,我可以获得分配给它的频道列表

queryset = Tariff.objects.prefetch_related('channels_list')
for tariff in queryset:
    channels_list = [tariff.channels_list.all()]
     print (channels_list)  

并获得下一组:

<QuerySet [<Channel: channelcategory1: channel1>, <Channel: channelcategory1: channel2>, <Channel: channelcategory2: channel3>]>

我想接收以下形式的查询集:

<QuerySet [<Channel: channelcategory1: channel1, channel2>, <Channel: channelcategory2: channel3>]>

我该怎么做?

我找到了解决这个问题的方法,一切都很简单。所以,我们要做的就是在providers/models.py下的classTariff:[=12下创建一个handler =]

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 + ":" + '\n' + channels_list_by_group + ". ")
    channel_list.append(channels_list_by_category + '\n' + '\n')
return ''.join(channel_list)

views.py 上使用此模板:

tariff = Tariff.objects.filter(is_active=True).prefetch_related('channels_list')

在 html 模板上:{{ tariff.get_channels|linebreaksbr }} 我们会得到我们需要的。

接下来就是定制了。例如,你可以在Django中使用templatetags,按照你需要的方式显示信息。