首页 > 解决方案 > 如何在django模型中快速选择相关表中的字段

问题描述

我正在尝试获取当前表中的所有值,并获取相关表中的一些字段。

class school(models.Model):
    school_name = models.CharField(max_length=256)
    school_type = models.CharField(max_length=128)
    school_address = models.CharField(max_length=256)

class hometown(models.Model):
    hometown_name = models.CharField(max_length=32)

class person(models.Model):
    person_name = models.CharField(max_length=128)
    person_id = models.CharField(max_length=128)
    person_school = models.ForeignKey(school, on_delete=models.CASCADE)
    person_ht = models.ForeignKey(hometown, on_delete=models.CASCADE)

如何快速选择我需要的所有信息到字典中进行渲染。会有很多人的记录,我输入了school_id,想得到这所学校的所有人,还想显示这些人的hometown_name。

我试过这样,可以得到我想要的信息。还有其他快速的方法吗?

m=person.objects.filter(person_school_id=1)
.values('id', 'person_name', 'person_id', 
school_name=F('person_school__school_name'), 
school_address=F('person_school__school_address'), 
hometown_name=F('person_ht__hometown_name'))

person_name, person_id, school_name, school_address, hometown_name

如果这个人有很多领域,列出所有值将是一项艰巨的工作。

我的意思是,是否有任何查询集可以将相关表的字段连接在一起,而无需在值中列出字段。也许是这样的:

m=person.objects.filter(person_school_id=1).XXXX.values()

它可以显示学校的所有价值观,以及家乡的所有价值观以及以m为单位的人的价值观,我可以

for x in m: 
   print(x.school_name, x.hometown_name, x.person_name)

标签: djangopython-3.xdjango-models

解决方案


prefetch_related您在查询集之上添加一个查询。

prefetch_data = Prefetch('person_set, hometown_set, school_set', queryset=m)

将在哪里prefetch_data准备您的数据库以获取相关表,并且m是您的原始过滤查询(因此在您的下面添加Person.objects.filter(...

然后你对数据库进行实际查询:

query = query.prefetch_related(prefetch_data)

其中 query 将是带有Person对象列表的实际结果查询(因此在该行下方添加该行prefetch_data)。

例子:

m=person.objects.filter(person_school_id=1)
.values('id', 'person_name', 'person_id', 
school_name=F('person_school__school_name'), 
school_address=F('person_school__school_address'), 
hometown_name=F('person_ht__hometown_name'))

prefetch_data = Prefetch('person_set, hometown_set, school_set', queryset=m)

query = query.prefetch_related(prefetch_data)

在该示例中,我已将查询分解为更易于管理的部分,但您也可以在一个大行中完成整个事情(虽然不太易于阅读):

m=person.objects.filter(person_school_id=1)
.values('id', 'person_name', 'person_id', 
school_name=F('person_school__school_name'), 
school_address=F('person_school__school_address'), 
hometown_name=F('person_ht__hometown_name')).prefetch_related('person, hometown, school')

推荐阅读