【问题标题】:Get reverse relationship for item in a list of dictionaries获取字典列表中项目的反向关系
【发布时间】:2018-03-07 16:25:13
【问题描述】:

我有一个字典列表('DailyEnrollment' 对象的查询集),如下所示:

[
{'location_id': 1, 'student_count': 780}, 
{'location_id': 4, 'student_count': 535}, 
{'location_id': 6, 'student_count': 496}
]

有一个 Location 对象具有属性 name - 此列表中的 location_idLocation 对象相关,但它不是外键(在模型),因为在我们的项目中其他应用程序如何与之交互。

有没有一种简单的方法来遍历这个列表,为location_id 获取每个字典location.name 并将其作为location_name 附加到字典中?

我正在考虑在列表推导中使用字典推导 - 但我不确定那是多么 Pythonic。

型号:

class Location(models.Model):
    name = models.CharField(max_length=50)
    short_name = models.CharField(max_length=50)

DailyEnrollment 是从使用外部数据构建的视图中获取的数据

class DailyEnrollment(SchoolModel):
    id            = models.IntegerField(db_column='ID', primary_key=True)
    location_id   = models.IntegerField(db_column='schoolID')
    grade         = models.CharField(db_column='grade', max_length=10)
    end_year      = models.IntegerField(db_column='endYear')
    run_date      = models.DateField(db_column='runDate')
    student_count = models.IntegerField(db_column='studentCount')

在视图中,这就是我获取每日注册的方式

# get past enrollments
    past_daily_enrollments = DailyEnrollment.objects.filter(
                run_date=datetime.strptime(since_date, '%m-%d-%Y'),
                location_id__lte='31',
                end_year='2018')

我创建了一个“新列表”数据,所有内容都按location_id 分组,总数为student_count

location_data = past_daily_enrollments.values('location_id').annotate(
    student_count=Sum('student_count')
)

我就是这样解决我所问的问题的。我有“location_data”,这是我的字典列表。

【问题讨论】:

  • 这是用 Django 写的吗?
  • 这个问题不完整。提供(样本)所有必要的数据结构和所需的输出。
  • 您应该能够使用您已经获得的 QuerySet 获取 Location.name。如果您想知道如何执行此操作,请告诉我。
  • @Tobias 那太好了!我只是不确定如何使用该 QuerySet 获取那些 Location 名称 - 我总是可以附加这些结果。
  • @timgeb - 我更新了更多信息。

标签: python django list dictionary


【解决方案1】:

您的模型不正确。我怀疑它们是通过对现有数据库运行inspectdb 生成的;这样做的问题之一是它有时无法检测到外键。但是,在您的情况下,location_id 显然是 Location 的外键,因此您应该这样声明:

location = models.ForeignKey('Location', db_column='schoolID')

完成此操作后,您可以通过值调用中的双下划线语法简单地遵循关系:

past_daily_enrollments.values('location__name')...

【讨论】:

  • 不幸的是,由于这个应用程序的范围(这里有多个应用程序在玩),模型是正确的。我现在看到location_id 不是直接的 FK 关系。我会修改我的问题。
  • 您需要提供更多信息。如果location_id 不是 Location 对象的 ID,那么它是什么?您希望如何到达相关地点?
  • 虽然由于我们的限制,它不是模型中的直接 FK 关系,但 location_id 确实 匹配适当位置项的主键。所以我不得不手动协调它们,因为我认为没有真正的“Django”方式来获得这种关系(因为模型中不存在关系)。
【解决方案2】:

所以(暂时)我通过几个步骤手动协调它们。

首先我使用我的位置数据并获取所有 ID 的列表,如下所示:

location_ids   = [s['location_id'] for s in location_data]

然后我得到这些 ID 的 Location 对象:

location_items = Location.objects.filter(
        id__in=location_ids
    )

然后我用 ID 和名称制作一个小字典:

location_names = [
        {'location_id':s.id, 'location_name': s.name}
        for s in location_items
    ]

然后我将两个字典列表链接在一起,并根据将每个字典绑定在一起的“location_id”从它们中创建一个新列表。

additional_location_data  = defaultdict(dict)
for d in chain(past_enrollments, location_names):
    additional_location_data[d['location_id']].update(d)

这有助于协调 location_id 与 Location 对象的名称,并将名称放入字典中(列表内)的适当位置。

它现在可能相当“丑陋” - 但我会担心以后清理它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-10
    • 2020-07-14
    • 2021-12-23
    • 2019-09-18
    • 1970-01-01
    • 2014-03-14
    • 1970-01-01
    • 2013-08-22
    相关资源
    最近更新 更多