【问题标题】:How to pull data from a related model in a many-to-many relationship?如何从多对多关系的相关模型中提取数据?
【发布时间】:2021-07-15 06:52:04
【问题描述】:

因此,我想在我的项目中以多对多关系将两个应用程序链接在一起。

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

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

现在我想做什么?假设资费对象包含4个渠道,有不同的类别,我们大致得到如下图:资费A有4个渠道来自2 个不同的渠道类别,例如“超级”资费有

['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)

【问题讨论】:

    标签: python-3.x django django-views many-to-many relationship


    【解决方案1】:

    此代码将起作用:

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

    【讨论】:

    • 不幸的是它没有用。不显示任何信息。空列表:(
    • 你能提供一段代码来打印它吗?代码的哪一部分不起作用?在我的代码中,我创建了一个字典,然后您应该根据需要打印 dict。
    • 是的,当然,现在我将尝试说明。我现在将更正我的问题并说明您想要什么,并说明这是您解决此问题的建议。
    • @EchoFoe 当然它在你写 if 语句时不起作用,起初的 dict 总是空的。我没这么写。你需要打印出:category_channel_dict
    • 我按照说明做了一切并显示信息 print(category_channel_dict) => defaultdict(, {})
    【解决方案2】:

    成功了。不知道好看不好看,但是在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;频道名称_2;频道名称_3;频道名称_4。

    ChannelCategory_2:ChannelName_5;频道名称_6。

    ChannelCategory_3:ChannelName_6 等

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-02
      • 1970-01-01
      • 2019-02-09
      • 2018-10-21
      相关资源
      最近更新 更多