MCPcopy
hub / github.com/django/django / _get_defer_select_mask

Method _get_defer_select_mask

django/db/models/sql/query.py:816–858  ·  view source on GitHub ↗
(self, opts, mask, select_mask=None)

Source from the content-addressed store, hash-verified

814 self.extra_order_by = rhs.extra_order_by or self.extra_order_by
815
816 def _get_defer_select_mask(self, opts, mask, select_mask=None):
817 if select_mask is None:
818 select_mask = {}
819 select_mask[opts.pk] = {}
820 # All concrete fields and related objects that are not part of the
821 # defer mask must be included. If a relational field is encountered it
822 # gets added to the mask for it be considered if `select_related` and
823 # the cycle continues by recursively calling this function.
824 for field in opts.concrete_fields + opts.related_objects:
825 field_mask = mask.pop(field.name, None)
826 field_att_mask = None
827 if field_attname := getattr(field, "attname", None):
828 field_att_mask = mask.pop(field_attname, None)
829 if field_mask is None and field_att_mask is None:
830 select_mask.setdefault(field, {})
831 elif field_mask:
832 if not field.is_relation:
833 raise FieldError(next(iter(field_mask)))
834 # Virtual fields such as many-to-many and generic foreign keys
835 # cannot be effectively deferred. Historically, they were
836 # allowed to be passed to QuerySet.defer(). Ignore such field
837 # references until a layer of validation at mask alteration
838 # time is eventually implemented.
839 if field.many_to_many:
840 continue
841 field_select_mask = select_mask.setdefault(field, {})
842 related_model = field.related_model._meta.concrete_model
843 self._get_defer_select_mask(
844 related_model._meta, field_mask, field_select_mask
845 )
846 # Remaining defer entries must be references to filtered relations
847 # otherwise they are surfaced as missing field errors.
848 for field_name, field_mask in mask.items():
849 if filtered_relation := self._filtered_relations.get(field_name):
850 relation = opts.get_field(filtered_relation.relation_name)
851 field_select_mask = select_mask.setdefault((field_name, relation), {})
852 related_model = relation.related_model._meta.concrete_model
853 self._get_defer_select_mask(
854 related_model._meta, field_mask, field_select_mask
855 )
856 else:
857 opts.get_field(field_name)
858 return select_mask
859
860 def _get_only_select_mask(self, opts, mask, select_mask=None):
861 if select_mask is None:

Callers 1

get_select_maskMethod · 0.95

Calls 6

FieldErrorClass · 0.90
popMethod · 0.45
setdefaultMethod · 0.45
itemsMethod · 0.45
getMethod · 0.45
get_fieldMethod · 0.45

Tested by

no test coverage detected