首页 > 解决方案 > 如何对从查询集多对多字段中提取的列表进行分组?

问题描述

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

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>]>

我怎样才能做到这一点?

标签: python-3.xdjangogroup-byormmany-to-many

解决方案


我找到了这个问题的解决方案,一切都很简单。所以,我们需要做的是在providers/models.py中的Tariff 类下创建一个处理程序:

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 模板上:{{ duty.get_channels|linebreaksbr }} 我们会得到我们需要的。

然后就是定制了。例如,您可以在 Django 中使用模板标签,并按照您需要的方式显示信息。


推荐阅读