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

Posted

技术标签:

【中文标题】如何对从查询集多对多字段中提取的列表进行分组?【英文标题】:How can you group a list extracted from queryset many-to-many field? 【发布时间】:2021-07-27 12:15:41 【问题描述】:

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

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)  

并获得下一组:

,,]>

我想收到如下形式的查询集:

channelcategory1: channel1, channel2>, channelcategory2: channel3>]>

我该怎么做?

【问题讨论】:

【参考方案1】:

我找到了这个问题的解决方案,一切都很简单。所以,我们需要做的就是在 providers/models.pyclass 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 中使用 templatetags 并按照您需要的方式显示信息。

【讨论】:

以上是关于如何对从查询集多对多字段中提取的列表进行分组?的主要内容,如果未能解决你的问题,请参考以下文章

Django - 查询列表中的任何项目在多对多字段中的任何对象

如何通过 Eloquent 中具有多对多关系的外部表中的列聚合进行分组?

Django如何过滤多对多字段中的对象,而不是原始查询集

如何查询多对多

在 django 中查询多对多字段会产生一个空查询集

Django ORM:构造查询,该查询将在多对多字段的最后位置的对象中的字段上查找匹配项