如何在Django模型中快速选择相关表中的字段

时间:2019-04-01 09:29:18

标签: django python-3.x django-models

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

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

人名,人名,学校名,学校地址,家乡名

如果此人有很多字段,要列出所有值将很困难。

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

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)

1 个答案:

答案 0 :(得分:0)

您在查询集的顶部添加了一个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)

查询将是实际结果查询,其中包含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')