【问题标题】:Combining prefetch_related() and only() in a Django QuerySet在 Django QuerySet 中结合 prefetch_related() 和 only()
【发布时间】:2013-08-15 00:09:38
【问题描述】:

我正在尝试执行以下查询:

ParentModel.objects.prefetch_related('child_model').only('parent_attribute', 'childs__child_atrtibute').all()

它似乎不起作用。 Django 抛出以下异常:

'RelatedObject' object has no attribute 'rel'

Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/django/core/handlers/base.py", line 115, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "/Library/Python/2.7/site-packages/django/contrib/auth/decorators.py", line 25, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/Library/Python/2.7/site-packages/django/contrib/auth/decorators.py", line 25, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/Library/Python/2.7/site-packages/django/utils/decorators.py", line 91, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/…path_to_my_app…/models.py", line 123, in _nested_commit_on_success
    return commit_on_success(*args, **kwds)
  File "/Library/Python/2.7/site-packages/django/db/transaction.py", line 223, in inner
    return func(*args, **kwargs)
  File "/…path_to_my_app…/views.py", line 1047, in my_veiw_function
    MyParentModel.objects.prefetch_related('my_child_model').only('my_parent_attribute', 'my_child_model__my_child_attribute').all():
  File "/Library/Python/2.7/site-packages/django/db/models/query.py", line 102, in __iter__
    len(self)
  File "/Library/Python/2.7/site-packages/django/db/models/query.py", line 90, in __len__
    self._result_cache = list(self.iterator())
  File "/Library/Python/2.7/site-packages/django/db/models/query.py", line 258, in iterator
    only_load = self.query.get_loaded_field_names()
  File "/Library/Python/2.7/site-packages/django/db/models/sql/query.py", line 1888, in get_loaded_field_names
    self.deferred_to_data(collection, self.get_loaded_field_names_cb)
  File "/Library/Python/2.7/site-packages/django/db/models/sql/query.py", line 591, in deferred_to_data
    cur_model = source.rel.to
AttributeError: 'RelatedObject' object has no attribute 'rel'

如果我从 only() 方法中删除 childs__child_atrtibute 参数,一切都会按预期工作,但我的查询返回不必要的数据。

Django 手册说我们可以将only()defer() 与来自select_related() 的字段结合起来。

但是有没有办法将only() 与来自prefetch_related() 的字段一起使用?

我后来尝试在我的代码中使用 ChildModel.objects.only('child_attribute').all(),但它只会生成大量查询,而不是使用来自 prefetch_related() 的缓存结果。

我正在使用 Django 1.5。

【问题讨论】:

标签: django django-queryset


【解决方案1】:

我知道我在这里可能迟到了,而不是根据问题的要求(Django 1.5),但如果这对任何人有帮助......

从 Django 1.7 开始,使用 Prefetch 对象,这大概可以实现如下:

ParentModel.objects.prefetch_related(
    Prefetch(
        'child_model',
        query_set=ChildModel.objects.all().only(
             'parent_attribute', 'childs__child_atrtibute'
        )
    )
)

【讨论】:

    猜你喜欢
    • 2014-10-12
    • 2013-02-23
    • 1970-01-01
    • 2015-01-12
    • 2015-04-18
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 2017-10-08
    相关资源
    最近更新 更多