[英]How to get all the related fields from a query set in Django?
I have two models, Session
and SessionType
which have a many-to-one relationship. 我有两个模型, Session
和SessionType
具有多对一的关系。 There is also a Family
foreign key on Session
, like so: 在Session
上还有一个Family
外键,如下所示:
from django.db import models
class SesssionType(models.Model):
pass
class Session(models.Model):
session_type = models.ForeignKey('SessionType')
family = models.ForeignKey('Family')
For a certain instance family
of Family
, I have several Session
objects in the session_set
: 对于Family
的某个特定实例family
,我在session_set
有几个Session
对象:
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>]>
I would like to get a queryset containing the SessionType
s of these Session
s, similar to the following list: 我想获得一个包含这些Session
的SessionType
的查询集,类似于以下列表:
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>]
It seems like the select_related
method is meant for this, but calling it doesn't produce the desired result: 似乎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>]>
As seen above, the call to select_related()
produced a query set with Session
objects, and not SessionType
objects. 如上所示,对select_related()
的调用产生了一个包含Session
对象而不是SessionType
对象的查询集。 How can I get the SessionType
objects? 如何获取SessionType
对象?
I worked around this problem by filtering all SessionType
objects, like so: 我通过过滤所有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>]>
However, I have an inkling that this is less efficient than just getting the corresponding session_type
from the Session
objects in the family.session_set
, so explanations as to why select_related()
is not working as expected are still most welcome. 但是,我有一个暗示,即效率不如仅从family.session_set
的Session
对象获取相应的session_type
,因此,仍然非常欢迎对为什么select_related()
无法按预期工作的解释。
as you say you can use new query set to select all SessionType
objects. 如您所说,您可以使用新的查询集来选择所有SessionType
对象。
but select_related
usage is different 但是select_related
用法不同
according to Django documentation and all I used select_related not change queryset object type. 根据Django文档,我使用的所有select_related都不会更改queryset对象类型。 but only select all related objects from database by one query. 但只能通过一个查询从数据库中选择所有相关对象。 for example see this query: 例如,请参见以下查询:
for item in family.session_set.select_related('session_type').all():
print item.session_type
hits database once but when you write this: 一次访问数据库,但是在您编写此代码时:
for item in family.session_set.all():
print item.session_type
for every print one database hit occurred and one database hit for base query occurred. 对于每次打印,都会发生一个数据库命中,并且发生一个针对基本查询的数据库命中。 its not important for little data but when your data is too large your site went slow without select_related. 这对于少量数据并不重要,但是当数据太大时,如果没有select_related,您的网站就会变慢。 but be aware of using it. 但要注意使用它。 if you use it too much the action is opposite and your site went slow. 如果使用过多,则操作相反,并且网站运行缓慢。
see more on https://docs.djangoproject.com/en/2.0/ref/models/querysets/#select-related 在https://docs.djangoproject.com/en/2.0/ref/models/querysets/#select-related上查看更多
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.