获取字典列表中项目的反向关系

时间:2018-03-07 16:25:14

标签: python django list dictionary

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

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

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

是否有一种简单的方法可以遍历此列表,获取location.name的每个词典location_id并将其作为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',这是我的词典列表。

2 个答案:

答案 0 :(得分:0)

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

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

完成后,您只需通过值调用中的双下划线语法来关注该关系:

past_daily_enrollments.values('location__name')...

答案 1 :(得分:0)

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

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

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

然后我获取这些ID的位置对象:

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对象的名称进行协调,并将名称放在相应位置的字典(列表内)中。

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