Django在Queryset中获取外键对象

Posted

技术标签:

【中文标题】Django在Queryset中获取外键对象【英文标题】:Django get foreign key object inside Queryset 【发布时间】:2017-10-03 23:16:05 【问题描述】:

我有 3 个模型:

class Event(models.Model):
    cur_datetime = models.DateTimeField(default=datetime.datetime(1970, 1, 1, 0, 0, 0, 0, pytz.UTC), blank=True, null=True)
    week_no = models.IntegerField()
    day_no = models.IntegerField()

class SubEvent(models.Model):
    event = models.ForeignKey(Event, on_delete=models.CASCADE)
    version = models.IntegerField()

class SubSubEvent(models.Model):
    sub_event = models.ForeignKey(SubEvent, on_delete=models.CASCADE)
    length = models.IntegerField()

我想从SubSubEvent 模型中获取一个查询集,其中包含作为一个对象的所有外键。我现在拥有的是:

querySet = SubSubEvent.objects.filter(sub_event__event__cur_datetime__range=[from_date, to_date])

这将返回一个查询集,并使用 for 循环在每个对象上获取 __dict__,我得到如下内容:

'event_id': 1, '_state': <django.db.models.base.ModelState object at 0x7fd7d9cefeb8>, 'id': 10, 'length': '1'

这只是我想要实现的查询的一部分。我真正想要的是event_id 中的所有字段,而不仅仅是id 数字。换句话说,来自Event 的所有字段(包括数据)加上SubEvent 加上SubSubEvent 在一个查询集中。此查询集应包含具有 cur_datetime、week_no、day_no、version 和 length 的对象。

【问题讨论】:

我不太明白:您的查询提供了SubSubEvent 实例,您可以从中访问相关的SubEventEvent 实例,然后访问它们的所有属性(例如querySet.first().sub_event.event.cur_datetime,等)。 【参考方案1】:

听起来您正在寻找select_related()

qs = SubSubEvent.objects \
    .select_related('sub_event__event') \
    .filter(sub_event__event__cur_datetime__range=[from_date, to_date])

然后您可以访问相关的SubEventEvent 资源,而无需访问数据库。

sub_sub_event = qs[0]
sub_event = sub_sub_event.sub_event    # doesn't hit the database
event = sub_sub_event.sub_event.event  # doesn't hit the database

【讨论】:

感谢您的回答,它正在正常工作。我只是想也许有一种方法可以将qs 包含eventsub_event 的所有文件作为单个变量。例如,sub_sub_event = qs[0] 是否有可能返回所有字段,包括来自外键的字段? (在这种情况下我们可以跳过sub_event = sub_sub_event.sub_eventsub_event = sub_sub_event.sub_event 您可能对multi-table inheritance感兴趣。

以上是关于Django在Queryset中获取外键对象的主要内容,如果未能解决你的问题,请参考以下文章

django queryset过滤外键

视图中的Django外键 - 获取列表中每个用户显示的第一个图像

获取 Django 对象并将其返回包装在 QuerySet 中的函数?

django模型系统

从 Django QuerySet 中获取所有相关的多对多对象

具有复杂外键遍历的棘手 Django QuerySet