mirror of
https://github.com/django/django.git
synced 2025-08-09 21:38:18 +00:00
Fixed #17485 -- Made defer work with select_related
This commit tackles a couple of issues. First, in certain cases there were some mixups if field.attname or field.name should be deferred. Field.attname is now always used. Another issue tackled is a case where field is both deferred by .only(), and selected by select_related. This case is now an error. A lot of thanks to koniiiik (Michal Petrucha) for the patch, and to Andrei Antoukh for review.
This commit is contained in:
parent
5318783027
commit
b6c356b7bb
9 changed files with 81 additions and 21 deletions
|
@ -126,18 +126,19 @@ class DeferredAttribute(object):
|
|||
return None
|
||||
|
||||
|
||||
def select_related_descend(field, restricted, requested, reverse=False):
|
||||
def select_related_descend(field, restricted, requested, load_fields, reverse=False):
|
||||
"""
|
||||
Returns True if this field should be used to descend deeper for
|
||||
select_related() purposes. Used by both the query construction code
|
||||
(sql.query.fill_related_selections()) and the model instance creation code
|
||||
(query.get_cached_row()).
|
||||
(query.get_klass_info()).
|
||||
|
||||
Arguments:
|
||||
* field - the field to be checked
|
||||
* restricted - a boolean field, indicating if the field list has been
|
||||
manually restricted using a requested clause)
|
||||
* requested - The select_related() dictionary.
|
||||
* load_fields - the set of fields to be loaded on this model
|
||||
* reverse - boolean, True if we are checking a reverse select related
|
||||
"""
|
||||
if not field.rel:
|
||||
|
@ -151,6 +152,14 @@ def select_related_descend(field, restricted, requested, reverse=False):
|
|||
return False
|
||||
if not restricted and field.null:
|
||||
return False
|
||||
if load_fields:
|
||||
if field.name not in load_fields:
|
||||
if restricted and field.name in requested:
|
||||
raise InvalidQuery("Field %s.%s cannot be both deferred"
|
||||
" and traversed using select_related"
|
||||
" at the same time." %
|
||||
(field.model._meta.object_name, field.name))
|
||||
return False
|
||||
return True
|
||||
|
||||
# This function is needed because data descriptors must be defined on a class
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue