如何从Django中的查询集中获取所有相关字段?

时间:2018-07-09 23:52:34

标签: python django django-queryset

我有两个模型,SessionSessionType具有多对一的关系。 Family上还有一个Session外键,如下所示:

from django.db import models


class SesssionType(models.Model):
    pass


class Session(models.Model):
    session_type = models.ForeignKey('SessionType')
    family = models.ForeignKey('Family')

对于family的某个特定实例Family,我在Session中有几个session_set对象:

ipdb> family.session_set.all()
<QuerySet [<Session: Welcome>, <Session: Breastfeeding Preparation - Timothy Anderson>, <Session: First-Time Parents: The Basics of Birth>, <Session: Initial Postpartum Lactation>, <Session: Sleep Techniques for New Babies>, <Session: Breastfeeding Preparation>, <Session: Newborn Care Basics>, <Session: Easing the Transition Back to Work>, <Session: Preparing for Parenting>, <Session: Decoding Baby Cues>, <Session: Postpartum Doula Support>, <Session: First-Time Parents: Birth Prep Q&A>, <Session: Postpartum Lactation Follow-Up>, <Session: Sleep Training for 4 Months & Beyond>, <Session: Mental Wellness in Pregnancy>, <Session: Infant CPR>, <Session: Prenatal Pelvic Physical Therapy>, <Session: Prenatal Massage>]>

我想获得一个包含以下SessionType个中的Session个的查询集,类似于以下列表:

ipdb> [session.session_type for session in family.session_set.all()]
[<SessionType: Welcome>, <SessionType: Breastfeeding Preparation>, <SessionType: First-Time Parents: The Basics of Birth>, <SessionType: Initial Postpartum Lactation>, <SessionType: Sleep Techniques for New Babies>, <SessionType: Breastfeeding Preparation>, <SessionType: Newborn Care Basics>, <SessionType: Easing the Transition Back to Work>, <SessionType: Preparing for Parenting>, <SessionType: Decoding Baby Cues>, <SessionType: Postpartum Doula Support>, <SessionType: First-Time Parents: Birth Prep Q&A>, <SessionType: Postpartum Lactation Follow-Up>, <SessionType: Sleep Training for 4 Months & Beyond>, <SessionType: Mental Wellness in Pregnancy>, <SessionType: Infant CPR>, <SessionType: Prenatal Pelvic Physical Therapy>, <SessionType: Prenatal Massage>]

select_related方法似乎是为此目的而设计的,但是调用它并不会产生预期的结果:

ipdb> family.session_set.select_related('session_type')
<QuerySet [<Session: Welcome>, <Session: Breastfeeding Preparation - Timothy Anderson>, <Session: First-Time Parents: The Basics of Birth>, <Session: Initial Postpartum Lactation>, <Session: Sleep Techniques for New Babies>, <Session: Breastfeeding Preparation>, <Session: Newborn Care Basics>, <Session: Easing the Transition Back to Work>, <Session: Preparing for Parenting>, <Session: Decoding Baby Cues>, <Session: Postpartum Doula Support>, <Session: First-Time Parents: Birth Prep Q&A>, <Session: Postpartum Lactation Follow-Up>, <Session: Sleep Training for 4 Months & Beyond>, <Session: Mental Wellness in Pregnancy>, <Session: Infant CPR>, <Session: Prenatal Pelvic Physical Therapy>, <Session: Prenatal Massage>]>

如上所示,对select_related()的调用产生了一个包含Session对象而不是SessionType对象的查询集。如何获得SessionType对象?

2 个答案:

答案 0 :(得分:1)

我通过过滤所有"@material-ui/core": "^1.3.1", "@material-ui/icons": "^1.1.0", "react": "^16.4.1", "react-dom": "^16.4.1", 对象来解决此问题,如下所示:

SessionType

但是,我有一个暗示,即从ipdb> SessionType.objects.filter(session__family=family).order_by('session__session_number') <QuerySet [<SessionType: Welcome>, <SessionType: First-Time Parents: The Basics of Birth>, <SessionType: Initial Postpartum Lactation>, <SessionType: Sleep Techniques for New Babies>, <SessionType: Breastfeeding Preparation>, <SessionType: Newborn Care Basics>, <SessionType: Easing the Transition Back to Work>, <SessionType: Preparing for Parenting>, <SessionType: Decoding Baby Cues>, <SessionType: Postpartum Doula Support>, <SessionType: First-Time Parents: Birth Prep Q&A>, <SessionType: Postpartum Lactation Follow-Up>, <SessionType: Sleep Training for 4 Months & Beyond>, <SessionType: Mental Wellness in Pregnancy>, <SessionType: Infant CPR>, <SessionType: Prenatal Pelvic Physical Therapy>, <SessionType: Prenatal Massage>]> 中的session_type对象中获取相应的Session效率不高,因此解释了为什么family.session_set仍无法按预期工作,仍然是最受欢迎的。

答案 1 :(得分:1)

如您所说,您可以使用新的查询集来选择所有SessionType个对象。

但是select_related的用法不同

根据Django文档,我使用的所有select_related都不会更改queryset对象类型。但只能通过一个查询从数据库中选择所有相关对象。例如,请参见以下查询:

for item in family.session_set.select_related('session_type').all():
     print item.session_type

一次访问数据库,但是在您编写此代码时:

for item in family.session_set.all():
     print item.session_type

对于每个打印,发生一个数据库命中,并且发生一个针对基本查询的数据库命中。这对于少量数据并不重要,但是当数据太大时,如果没有select_related,您的网站就会变慢。但要注意使用它。如果使用过多,操作将相反,并且网站运行缓慢。

有关https://docs.djangoproject.com/en/2.0/ref/models/querysets/#select-related的更多信息