1import bisect
2import copy
3from collections import defaultdict
4
5from django.apps import apps
6from django.conf import settings
7from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured
8from django.core.signals import setting_changed
9from django.db import connections
10from django.db.models import (
11 AutoField,
12 CompositePrimaryKey,
13 Manager,
14 OrderWrt,
15 UniqueConstraint,
16)
17from django.db.models.fields import composite
18from django.db.models.query_utils import PathInfo
19from django.utils.datastructures import ImmutableList, OrderedSet
20from django.utils.functional import cached_property
21from django.utils.module_loading import import_string
22from django.utils.text import camel_case_to_spaces, format_lazy
23from django.utils.translation import override
24
25PROXY_PARENTS = object()
26
27EMPTY_RELATION_TREE = ()
28
29IMMUTABLE_WARNING = (
30 "The return type of '%s' should never be mutated. If you want to manipulate this "
31 "list for your own use, make a copy first."
32)
33
34DEFAULT_NAMES = (
35 "verbose_name",
36 "verbose_name_plural",
37 "db_table",
38 "db_table_comment",
39 "ordering",
40 "unique_together",
41 "permissions",
42 "get_latest_by",
43 "order_with_respect_to",
44 "app_label",
45 "db_tablespace",
46 "abstract",
47 "managed",
48 "proxy",
49 "swappable",
50 "auto_created",
51 "apps",
52 "default_permissions",
53 "select_on_save",
54 "default_related_name",
55 "required_db_features",
56 "required_db_vendor",
57 "base_manager_name",
58 "default_manager_name",
59 "indexes",
60 "constraints",
61)
62
63
64def normalize_together(option_together):
65 """
66 option_together can be either a tuple of tuples, or a single
67 tuple of two strings. Normalize it to a tuple of tuples, so that
68 calling code can uniformly expect that.
69 """
70 try:
71 if not option_together:
72 return ()
73 if not isinstance(option_together, (tuple, list)):
74 raise TypeError
75 first_element = option_together[0]
76 if not isinstance(first_element, (tuple, list)):
77 option_together = (option_together,)
78 # Normalize everything to tuples
79 return tuple(tuple(ot) for ot in option_together)
80 except TypeError:
81 # If the value of option_together isn't valid, return it
82 # verbatim; this will be picked up by the check framework later.
83 return option_together
84
85
86def make_immutable_fields_list(name, data):
87 return ImmutableList(data, warning=IMMUTABLE_WARNING % name)
88
89
90class Options:
91 FORWARD_PROPERTIES = {
92 "fields",
93 "many_to_many",
94 "concrete_fields",
95 "local_concrete_fields",
96 "_non_pk_concrete_field_names",
97 "_reverse_one_to_one_field_names",
98 "_forward_fields_map",
99 "managers",
100 "managers_map",
101 "base_manager",
102 "default_manager",
103 }
104 REVERSE_PROPERTIES = {"related_objects", "fields_map", "_relation_tree"}
105
106 default_apps = apps
107
108 def __init__(self, meta, app_label=None):
109 self._get_fields_cache = {}
110 self.local_fields = []
111 self.local_many_to_many = []
112 self.private_fields = []
113 self.local_managers = []
114 self.base_manager_name = None
115 self.default_manager_name = None
116 self.model_name = None
117 self.verbose_name = None
118 self.verbose_name_plural = None
119 self.db_table = ""
120 self.db_table_comment = ""
121 self.ordering = []
122 self._ordering_clash = False
123 self.indexes = []
124 self.constraints = []
125 self.unique_together = []
126 self.select_on_save = False
127 self.default_permissions = ("add", "change", "delete", "view")
128 self.permissions = []
129 self.object_name = None
130 self.app_label = app_label
131 self.get_latest_by = None
132 self.order_with_respect_to = None
133 self.db_tablespace = settings.DEFAULT_TABLESPACE
134 self.required_db_features = []
135 self.required_db_vendor = None
136 self.meta = meta
137 self.pk = None
138 self.auto_field = None
139 self.abstract = False
140 self.managed = True
141 self.proxy = False
142 # For any class that is a proxy (including automatically created
143 # classes for deferred object loading), proxy_for_model tells us
144 # which class this model is proxying. Note that proxy_for_model
145 # can create a chain of proxy models. For non-proxy models, the
146 # variable is always None.
147 self.proxy_for_model = None
148 # For any non-abstract class, the concrete class is the model
149 # in the end of the proxy_for_model chain. In particular, for
150 # concrete models, the concrete_model is always the class itself.
151 self.concrete_model = None
152 self.swappable = None
153 self.parents = {}
154 self.auto_created = False
155
156 # List of all lookups defined in ForeignKey 'limit_choices_to' options
157 # from *other* models. Needed for some admin checks. Internal use only.
158 self.related_fkey_lookups = []
159
160 # A custom app registry to use, if you're making a separate model set.
161 self.apps = self.default_apps
162
163 self.default_related_name = None
164
165 @property
166 def label(self):
167 return "%s.%s" % (self.app_label, self.object_name)
168
169 @property
170 def label_lower(self):
171 return "%s.%s" % (self.app_label, self.model_name)
172
173 @property
174 def app_config(self):
175 # Don't go through get_app_config to avoid triggering imports.
176 return self.apps.app_configs.get(self.app_label)
177
178 def contribute_to_class(self, cls, name):
179 from django.db import connection
180 from django.db.backends.utils import truncate_name
181
182 cls._meta = self
183 self.model = cls
184 # First, construct the default values for these options.
185 self.object_name = cls.__name__
186 self.model_name = self.object_name.lower()
187 self.verbose_name = camel_case_to_spaces(self.object_name)
188
189 # Store the original user-defined values for each option,
190 # for use when serializing the model definition
191 self.original_attrs = {}
192
193 # Next, apply any overridden values from 'class Meta'.
194 if self.meta:
195 meta_attrs = self.meta.__dict__.copy()
196 for name in self.meta.__dict__:
197 # Ignore any private attributes that Django doesn't care about.
198 # NOTE: We can't modify a dictionary's contents while looping
199 # over it, so we loop over the *original* dictionary instead.
200 if name.startswith("_"):
201 del meta_attrs[name]
202 for attr_name in DEFAULT_NAMES:
203 if attr_name in meta_attrs:
204 setattr(self, attr_name, meta_attrs.pop(attr_name))
205 self.original_attrs[attr_name] = getattr(self, attr_name)
206 elif hasattr(self.meta, attr_name):
207 setattr(self, attr_name, getattr(self.meta, attr_name))
208 self.original_attrs[attr_name] = getattr(self, attr_name)
209
210 self.unique_together = normalize_together(self.unique_together)
211 # App label/class name interpolation for names of constraints and
212 # indexes.
213 if not self.abstract:
214 self.constraints = self._format_names(self.constraints)
215 self.indexes = self._format_names(self.indexes)
216
217 # verbose_name_plural is a special case because it uses a 's'
218 # by default.
219 if self.verbose_name_plural is None:
220 self.verbose_name_plural = format_lazy("{}s", self.verbose_name)
221
222 # order_with_respect_and ordering are mutually exclusive.
223 self._ordering_clash = bool(self.ordering and self.order_with_respect_to)
224
225 # Any leftover attributes must be invalid.
226 if meta_attrs != {}:
227 raise TypeError(
228 "'class Meta' got invalid attribute(s): %s" % ",".join(meta_attrs)
229 )
230 else:
231 self.verbose_name_plural = format_lazy("{}s", self.verbose_name)
232 del self.meta
233
234 # If the db_table wasn't provided, use the app_label + model_name.
235 if not self.db_table:
236 self.db_table = "%s_%s" % (self.app_label, self.model_name)
237 self.db_table = truncate_name(
238 self.db_table, connection.ops.max_name_length()
239 )
240
241 if self.swappable:
242 setting_changed.connect(self.setting_changed)
243
244 def _format_names(self, objs):
245 """App label/class name interpolation for object names."""
246 names = {"app_label": self.app_label.lower(), "class": self.model_name}
247 new_objs = []
248 for obj in objs:
249 obj = obj.clone()
250 obj.name %= names
251 new_objs.append(obj)
252 return new_objs
253
254 def _get_default_pk_class(self):
255 pk_class_path = getattr(
256 self.app_config,
257 "default_auto_field",
258 settings.DEFAULT_AUTO_FIELD,
259 )
260 if self.app_config and self.app_config._is_default_auto_field_overridden:
261 app_config_class = type(self.app_config)
262 source = (
263 f"{app_config_class.__module__}."
264 f"{app_config_class.__qualname__}.default_auto_field"
265 )
266 else:
267 source = "DEFAULT_AUTO_FIELD"
268 if not pk_class_path:
269 raise ImproperlyConfigured(f"{source} must not be empty.")
270 try:
271 pk_class = import_string(pk_class_path)
272 except ImportError as e:
273 msg = (
274 f"{source} refers to the module '{pk_class_path}' that could "
275 f"not be imported."
276 )
277 raise ImproperlyConfigured(msg) from e
278 if not issubclass(pk_class, AutoField):
279 raise ValueError(
280 f"Primary key '{pk_class_path}' referred by {source} must "
281 f"subclass AutoField."
282 )
283 return pk_class
284
285 def _prepare(self, model):
286 if self.order_with_respect_to:
287 # The app registry will not be ready at this point, so we cannot
288 # use get_field().
289 query = self.order_with_respect_to
290 try:
291 self.order_with_respect_to = next(
292 f
293 for f in self._get_fields(reverse=False)
294 if f.name == query or f.attname == query
295 )
296 except StopIteration:
297 raise FieldDoesNotExist(
298 "%s has no field named '%s'" % (self.object_name, query)
299 )
300
301 self.ordering = ("_order",)
302 if not any(
303 isinstance(field, OrderWrt) for field in model._meta.local_fields
304 ):
305 model.add_to_class("_order", OrderWrt())
306 else:
307 self.order_with_respect_to = None
308
309 if self.pk is None:
310 if self.parents:
311 # Promote the first parent link in lieu of adding yet another
312 # field.
313 field = next(iter(self.parents.values()))
314 # Look for a local field with the same name as the
315 # first parent link. If a local field has already been
316 # created, use it instead of promoting the parent
317 already_created = [
318 fld for fld in self.local_fields if fld.name == field.name
319 ]
320 if already_created:
321 field = already_created[0]
322 field.primary_key = True
323 self.setup_pk(field)
324 else:
325 pk_class = self._get_default_pk_class()
326 auto = pk_class(verbose_name="ID", primary_key=True, auto_created=True)
327 model.add_to_class("id", auto)
328
329 def add_manager(self, manager):
330 self.local_managers.append(manager)
331 self._expire_cache()
332
333 def add_field(self, field, private=False):
334 # Insert the given field in the order in which it was created, using
335 # the "creation_counter" attribute of the field.
336 # Move many-to-many related fields from self.fields into
337 # self.many_to_many.
338 if private:
339 self.private_fields.append(field)
340 elif field.is_relation and field.many_to_many:
341 bisect.insort(self.local_many_to_many, field)
342 else:
343 bisect.insort(self.local_fields, field)
344 self.setup_pk(field)
345
346 # If the field being added is a relation to another known field,
347 # expire the cache on this field and the forward cache on the field
348 # being referenced, because there will be new relationships in the
349 # cache. Otherwise, expire the cache of references *to* this field.
350 # The mechanism for getting at the related model is slightly odd -
351 # ideally, we'd just ask for field.related_model. However, related_model
352 # is a cached property, and all the models haven't been loaded yet, so
353 # we need to make sure we don't cache a string reference.
354 if (
355 field.is_relation
356 and hasattr(field.remote_field, "model")
357 and field.remote_field.model
358 ):
359 try:
360 field.remote_field.model._meta._expire_cache(forward=False)
361 except AttributeError:
362 pass
363 self._expire_cache()
364 else:
365 self._expire_cache(reverse=False)
366
367 def setup_pk(self, field):
368 if not self.pk and field.primary_key:
369 self.pk = field
370 field.serialize = False
371
372 def setup_proxy(self, target):
373 """
374 Do the internal setup so that the current model is a proxy for
375 "target".
376 """
377 self.pk = target._meta.pk
378 self.proxy_for_model = target
379 self.db_table = target._meta.db_table
380
381 def __repr__(self):
382 return "<Options for %s>" % self.object_name
383
384 def __str__(self):
385 return self.label_lower
386
387 def can_migrate(self, connection):
388 """
389 Return True if the model can/should be migrated on the `connection`.
390 `connection` can be either a real connection or a connection alias.
391 """
392 if self.proxy or self.swapped or not self.managed:
393 return False
394 if isinstance(connection, str):
395 connection = connections[connection]
396 if self.required_db_vendor:
397 return self.required_db_vendor == connection.vendor
398 if self.required_db_features:
399 return all(
400 getattr(connection.features, feat, False)
401 for feat in self.required_db_features
402 )
403 return True
404
405 @cached_property
406 def verbose_name_raw(self):
407 """Return the untranslated verbose name."""
408 if isinstance(self.verbose_name, str):
409 return self.verbose_name
410 with override(None):
411 return str(self.verbose_name)
412
413 @cached_property
414 def swapped(self):
415 """
416 Has this model been swapped out for another? If so, return the model
417 name of the replacement; otherwise, return None.
418
419 For historical reasons, model name lookups using get_model() are
420 case insensitive, so we make sure we are case insensitive here.
421 """
422 if self.swappable:
423 swapped_for = getattr(settings, self.swappable, None)
424 if swapped_for:
425 try:
426 swapped_label, swapped_object = swapped_for.split(".")
427 except ValueError:
428 # setting not in the format app_label.model_name
429 # raising ImproperlyConfigured here causes problems with
430 # test cleanup code - instead it is raised in get_user_model
431 # or as part of validation.
432 return swapped_for
433
434 if (
435 "%s.%s" % (swapped_label, swapped_object.lower())
436 != self.label_lower
437 ):
438 return swapped_for
439 return None
440
441 def setting_changed(self, *, setting, **kwargs):
442 if setting == self.swappable and "swapped" in self.__dict__:
443 del self.swapped
444
445 @cached_property
446 def managers(self):
447 managers = []
448 seen_managers = set()
449 bases = (b for b in self.model.mro() if hasattr(b, "_meta"))
450 for depth, base in enumerate(bases):
451 for manager in base._meta.local_managers:
452 if manager.name in seen_managers:
453 continue
454
455 manager = copy.copy(manager)
456 manager.model = self.model
457 seen_managers.add(manager.name)
458 managers.append((depth, manager.creation_counter, manager))
459
460 return make_immutable_fields_list(
461 "managers",
462 (m[2] for m in sorted(managers)),
463 )
464
465 @cached_property
466 def managers_map(self):
467 return {manager.name: manager for manager in self.managers}
468
469 @cached_property
470 def base_manager(self):
471 base_manager_name = self.base_manager_name
472 if not base_manager_name:
473 # Get the first parent's base_manager_name if there's one.
474 for parent in self.model.mro()[1:]:
475 if hasattr(parent, "_meta"):
476 if parent._base_manager.name != "_base_manager":
477 base_manager_name = parent._base_manager.name
478 break
479
480 if base_manager_name:
481 try:
482 return self.managers_map[base_manager_name]
483 except KeyError:
484 raise ValueError(
485 "%s has no manager named %r"
486 % (
487 self.object_name,
488 base_manager_name,
489 )
490 )
491
492 manager = Manager()
493 manager.name = "_base_manager"
494 manager.model = self.model
495 manager.auto_created = True
496 return manager
497
498 @cached_property
499 def default_manager(self):
500 default_manager_name = self.default_manager_name
501 if not default_manager_name and not self.local_managers:
502 # Get the first parent's default_manager_name if there's one.
503 for parent in self.model.mro()[1:]:
504 if hasattr(parent, "_meta"):
505 default_manager_name = parent._meta.default_manager_name
506 break
507
508 if default_manager_name:
509 try:
510 return self.managers_map[default_manager_name]
511 except KeyError:
512 raise ValueError(
513 "%s has no manager named %r"
514 % (
515 self.object_name,
516 default_manager_name,
517 )
518 )
519
520 if self.managers:
521 return self.managers[0]
522
523 @cached_property
524 def fields(self):
525 """
526 Return a list of all forward fields on the model and its parents,
527 excluding ManyToManyFields.
528
529 Private API intended only to be used by Django itself; get_fields()
530 combined with filtering of field properties is the public API for
531 obtaining this field list.
532 """
533
534 # For legacy reasons, the fields property should only contain forward
535 # fields that are not private or with a m2m cardinality. Therefore we
536 # pass these three filters as filters to the generator.
537 # The third lambda is a longwinded way of checking f.related_model - we don't
538 # use that property directly because related_model is a cached property,
539 # and all the models may not have been loaded yet; we don't want to cache
540 # the string reference to the related_model.
541 def is_not_an_m2m_field(f):
542 return not (f.is_relation and f.many_to_many)
543
544 def is_not_a_generic_relation(f):
545 return not (f.is_relation and f.one_to_many)
546
547 def is_not_a_generic_foreign_key(f):
548 return not (
549 f.is_relation
550 and f.many_to_one
551 and not (hasattr(f.remote_field, "model") and f.remote_field.model)
552 )
553
554 return make_immutable_fields_list(
555 "fields",
556 (
557 f
558 for f in self._get_fields(reverse=False)
559 if is_not_an_m2m_field(f)
560 and is_not_a_generic_relation(f)
561 and is_not_a_generic_foreign_key(f)
562 ),
563 )
564
565 @cached_property
566 def concrete_fields(self):
567 """
568 Return a list of all concrete fields on the model and its parents.
569
570 Private API intended only to be used by Django itself; get_fields()
571 combined with filtering of field properties is the public API for
572 obtaining this field list.
573 """
574 return make_immutable_fields_list(
575 "concrete_fields", (f for f in self.fields if f.concrete)
576 )
577
578 @cached_property
579 def local_concrete_fields(self):
580 """
581 Return a list of all concrete fields on the model.
582
583 Private API intended only to be used by Django itself; get_fields()
584 combined with filtering of field properties is the public API for
585 obtaining this field list.
586 """
587 return make_immutable_fields_list(
588 "local_concrete_fields", (f for f in self.local_fields if f.concrete)
589 )
590
591 @cached_property
592 def many_to_many(self):
593 """
594 Return a list of all many to many fields on the model and its parents.
595
596 Private API intended only to be used by Django itself; get_fields()
597 combined with filtering of field properties is the public API for
598 obtaining this list.
599 """
600 return make_immutable_fields_list(
601 "many_to_many",
602 (
603 f
604 for f in self._get_fields(reverse=False)
605 if f.is_relation and f.many_to_many
606 ),
607 )
608
609 @cached_property
610 def related_objects(self):
611 """
612 Return all related objects pointing to the current model. The related
613 objects can come from a one-to-one, one-to-many, or many-to-many field
614 relation type.
615
616 Private API intended only to be used by Django itself; get_fields()
617 combined with filtering of field properties is the public API for
618 obtaining this field list.
619 """
620 all_related_fields = self._get_fields(
621 forward=False, reverse=True, include_hidden=True
622 )
623 return make_immutable_fields_list(
624 "related_objects",
625 (
626 obj
627 for obj in all_related_fields
628 if not obj.hidden or obj.field.many_to_many
629 ),
630 )
631
632 @cached_property
633 def _forward_fields_map(self):
634 res = {}
635 fields = self._get_fields(reverse=False)
636 for field in fields:
637 res[field.name] = field
638 # Due to the way Django's internals work, get_field() should also
639 # be able to fetch a field by attname. In the case of a concrete
640 # field with relation, includes the *_id name too
641 try:
642 res[field.attname] = field
643 except AttributeError:
644 pass
645 return res
646
647 @cached_property
648 def fields_map(self):
649 res = {}
650 fields = self._get_fields(forward=False, include_hidden=True)
651 for field in fields:
652 res[field.name] = field
653 # Due to the way Django's internals work, get_field() should also
654 # be able to fetch a field by attname. In the case of a concrete
655 # field with relation, includes the *_id name too
656 try:
657 res[field.attname] = field
658 except AttributeError:
659 pass
660 return res
661
662 def get_field(self, field_name):
663 """
664 Return a field instance given the name of a forward or reverse field.
665 """
666 try:
667 # In order to avoid premature loading of the relation tree
668 # (expensive) we prefer checking if the field is a forward field.
669 return self._forward_fields_map[field_name]
670 except KeyError:
671 # If the app registry is not ready, reverse fields are
672 # unavailable, therefore we throw a FieldDoesNotExist exception.
673 if not self.apps.models_ready:
674 raise FieldDoesNotExist(
675 "%s has no field named '%s'. The app cache isn't ready yet, "
676 "so if this is an auto-created related field, it won't "
677 "be available yet." % (self.object_name, field_name)
678 )
679
680 try:
681 # Retrieve field instance by name from cached or just-computed
682 # field map.
683 return self.fields_map[field_name]
684 except KeyError:
685 raise FieldDoesNotExist(
686 "%s has no field named '%s'" % (self.object_name, field_name)
687 )
688
689 def get_base_chain(self, model):
690 """
691 Return a list of parent classes leading to `model` (ordered from
692 closest to most distant ancestor). This has to handle the case where
693 `model` is a grandparent or even more distant relation.
694 """
695 if not self.parents:
696 return []
697 if model in self.parents:
698 return [model]
699 for parent in self.parents:
700 res = parent._meta.get_base_chain(model)
701 if res:
702 res.insert(0, parent)
703 return res
704 return []
705
706 @cached_property
707 def all_parents(self):
708 """
709 Return all the ancestors of this model as a tuple ordered by MRO.
710 Useful for determining if something is an ancestor, regardless of lineage.
711 """
712 result = OrderedSet(self.parents)
713 for parent in self.parents:
714 for ancestor in parent._meta.all_parents:
715 result.add(ancestor)
716 return tuple(result)
717
718 def get_parent_list(self):
719 """
720 Return all the ancestors of this model as a list ordered by MRO.
721 Backward compatibility method.
722 """
723 return list(self.all_parents)
724
725 def get_ancestor_link(self, ancestor):
726 """
727 Return the field on the current model which points to the given
728 "ancestor". This is possible an indirect link (a pointer to a parent
729 model, which points, eventually, to the ancestor). Used when
730 constructing table joins for model inheritance.
731
732 Return None if the model isn't an ancestor of this one.
733 """
734 if ancestor in self.parents:
735 return self.parents[ancestor]
736 for parent in self.parents:
737 # Tries to get a link field from the immediate parent
738 parent_link = parent._meta.get_ancestor_link(ancestor)
739 if parent_link:
740 # In case of a proxied model, the first link
741 # of the chain to the ancestor is that parent
742 # links
743 return self.parents[parent] or parent_link
744
745 def get_path_to_parent(self, parent):
746 """
747 Return a list of PathInfos containing the path from the current
748 model to the parent model, or an empty list if parent is not a
749 parent of the current model.
750 """
751 if self.model is parent:
752 return []
753 # Skip the chain of proxy to the concrete proxied model.
754 proxied_model = self.concrete_model
755 path = []
756 opts = self
757 for int_model in self.get_base_chain(parent):
758 if int_model is proxied_model:
759 opts = int_model._meta
760 else:
761 final_field = opts.parents[int_model]
762 targets = (final_field.remote_field.get_related_field(),)
763 opts = int_model._meta
764 path.append(
765 PathInfo(
766 from_opts=final_field.model._meta,
767 to_opts=opts,
768 target_fields=targets,
769 join_field=final_field,
770 m2m=False,
771 direct=True,
772 filtered_relation=None,
773 )
774 )
775 return path
776
777 def get_path_from_parent(self, parent):
778 """
779 Return a list of PathInfos containing the path from the parent
780 model to the current model, or an empty list if parent is not a
781 parent of the current model.
782 """
783 if self.model is parent:
784 return []
785 model = self.concrete_model
786 # Get a reversed base chain including both the current and parent
787 # models.
788 chain = model._meta.get_base_chain(parent)
789 chain.reverse()
790 chain.append(model)
791 # Construct a list of the PathInfos between models in chain.
792 path = []
793 for i, ancestor in enumerate(chain[:-1]):
794 child = chain[i + 1]
795 link = child._meta.get_ancestor_link(ancestor)
796 path.extend(link.reverse_path_infos)
797 return path
798
799 def _populate_directed_relation_graph(self):
800 """
801 This method is used by each model to find its reverse objects. As this
802 method is very expensive and is accessed frequently (it looks up every
803 field in a model, in every app), it is computed on first access and then
804 is set as a property on every model.
805 """
806 related_objects_graph = defaultdict(list)
807
808 all_models = self.apps.get_models(include_auto_created=True)
809 for model in all_models:
810 opts = model._meta
811 # Abstract model's fields are copied to child models, hence we will
812 # see the fields from the child models.
813 if opts.abstract:
814 continue
815 fields_with_relations = (
816 f
817 for f in opts._get_fields(reverse=False, include_parents=False)
818 if f.is_relation and f.related_model is not None
819 )
820 for f in fields_with_relations:
821 if not isinstance(f.remote_field.model, str):
822 remote_label = f.remote_field.model._meta.concrete_model._meta.label
823 related_objects_graph[remote_label].append(f)
824
825 for model in all_models:
826 # Set the relation_tree using the internal __dict__. In this way
827 # we avoid calling the cached property. In attribute lookup,
828 # __dict__ takes precedence over a data descriptor (such as
829 # @cached_property). This means that the _meta._relation_tree is
830 # only called if related_objects is not in __dict__.
831 related_objects = related_objects_graph[
832 model._meta.concrete_model._meta.label
833 ]
834 model._meta.__dict__["_relation_tree"] = related_objects
835 # It seems it is possible that self is not in all_models, so guard
836 # against that with default for get().
837 return self.__dict__.get("_relation_tree", EMPTY_RELATION_TREE)
838
839 @cached_property
840 def _relation_tree(self):
841 return self._populate_directed_relation_graph()
842
843 def _expire_cache(self, forward=True, reverse=True):
844 # This method is usually called by apps.cache_clear(), when the
845 # registry is finalized, or when a new field is added.
846 if forward:
847 for cache_key in self.FORWARD_PROPERTIES:
848 if cache_key in self.__dict__:
849 delattr(self, cache_key)
850 if reverse and not self.abstract:
851 for cache_key in self.REVERSE_PROPERTIES:
852 if cache_key in self.__dict__:
853 delattr(self, cache_key)
854 self._get_fields_cache = {}
855
856 def get_fields(self, include_parents=True, include_hidden=False):
857 """
858 Return a list of fields associated to the model. By default, include
859 forward and reverse fields, fields derived from inheritance, but not
860 hidden fields. The returned fields can be changed using the parameters:
861
862 - include_parents: include fields derived from inheritance
863 - include_hidden: include fields that have a related_name that
864 starts with a "+"
865 """
866 if include_parents is False:
867 include_parents = PROXY_PARENTS
868 return self._get_fields(
869 include_parents=include_parents, include_hidden=include_hidden
870 )
871
872 def _get_fields(
873 self,
874 forward=True,
875 reverse=True,
876 include_parents=True,
877 include_hidden=False,
878 topmost_call=True,
879 ):
880 """
881 Internal helper function to return fields of the model.
882 * If forward=True, then fields defined on this model are returned.
883 * If reverse=True, then relations pointing to this model are returned.
884 * If include_hidden=True, then fields with is_hidden=True are returned.
885 * The include_parents argument toggles if fields from parent models
886 should be included. It has three values: True, False, and
887 PROXY_PARENTS. When set to PROXY_PARENTS, the call will return all
888 fields defined for the current model or any of its parents in the
889 parent chain to the model's concrete model.
890 """
891 if include_parents not in (True, False, PROXY_PARENTS):
892 raise TypeError(
893 "Invalid argument for include_parents: %s" % (include_parents,)
894 )
895 # This helper function is used to allow recursion in ``get_fields()``
896 # implementation and to provide a fast way for Django's internals to
897 # access specific subsets of fields.
898
899 # Creates a cache key composed of all arguments
900 cache_key = (forward, reverse, include_parents, include_hidden, topmost_call)
901
902 try:
903 # In order to avoid list manipulation. Always return a shallow copy
904 # of the results.
905 return self._get_fields_cache[cache_key]
906 except KeyError:
907 pass
908
909 fields = []
910 # Recursively call _get_fields() on each parent, with the same
911 # options provided in this call.
912 if include_parents is not False:
913 # In diamond inheritance it is possible that we see the same model
914 # from two different routes. In that case, avoid adding fields from
915 # the same parent again.
916 parent_fields = set()
917 for parent in self.parents:
918 if (
919 parent._meta.concrete_model != self.concrete_model
920 and include_parents == PROXY_PARENTS
921 ):
922 continue
923 for obj in parent._meta._get_fields(
924 forward=forward,
925 reverse=reverse,
926 include_parents=include_parents,
927 include_hidden=include_hidden,
928 topmost_call=False,
929 ):
930 if (
931 not getattr(obj, "parent_link", False)
932 or obj.model == self.concrete_model
933 ) and obj not in parent_fields:
934 fields.append(obj)
935 parent_fields.add(obj)
936
937 if reverse and not self.proxy:
938 # Tree is computed once and cached until the app cache is expired.
939 # It is composed of a list of fields pointing to the current model
940 # from other models.
941 all_fields = self._relation_tree
942 for field in all_fields:
943 # If hidden fields should be included or the relation is not
944 # intentionally hidden, add to the fields dict.
945 if include_hidden or not field.remote_field.hidden:
946 fields.append(field.remote_field)
947
948 if forward:
949 fields += self.local_fields
950 fields += self.local_many_to_many
951 # Private fields are recopied to each child model, and they get a
952 # different model as field.model in each child. Hence we have to
953 # add the private fields separately from the topmost call. If we
954 # did this recursively similar to local_fields, we would get field
955 # instances with field.model != self.model.
956 if topmost_call:
957 fields += self.private_fields
958
959 # In order to avoid list manipulation. Always
960 # return a shallow copy of the results
961 fields = make_immutable_fields_list("get_fields()", fields)
962
963 # Store result into cache for later access
964 self._get_fields_cache[cache_key] = fields
965 return fields
966
967 @cached_property
968 def total_unique_constraints(self):
969 """
970 Return a list of total unique constraints. Useful for determining set
971 of fields guaranteed to be unique for all rows.
972 """
973 return [
974 constraint
975 for constraint in self.constraints
976 if (
977 isinstance(constraint, UniqueConstraint)
978 and constraint.condition is None
979 and not constraint.contains_expressions
980 )
981 ]
982
983 @cached_property
984 def pk_fields(self):
985 return composite.unnest([self.pk])
986
987 @property
988 def is_composite_pk(self):
989 return isinstance(self.pk, CompositePrimaryKey)
990
991 @cached_property
992 def _property_names(self):
993 """Return a set of the names of the properties defined on the model."""
994 names = set()
995 seen = set()
996 for klass in self.model.__mro__:
997 names |= {
998 name
999 for name, value in klass.__dict__.items()
1000 if isinstance(value, property) and name not in seen
1001 }
1002 seen |= set(klass.__dict__)
1003 return frozenset(names)
1004
1005 @cached_property
1006 def _non_pk_concrete_field_names(self):
1007 """
1008 Return a set of the non-pk concrete field names defined on the model.
1009 """
1010 names = []
1011 all_pk_fields = set(self.pk_fields)
1012 for parent in self.all_parents:
1013 all_pk_fields.update(parent._meta.pk_fields)
1014 for field in self.concrete_fields:
1015 if field not in all_pk_fields:
1016 names.append(field.name)
1017 if field.name != field.attname:
1018 names.append(field.attname)
1019 return frozenset(names)
1020
1021 @cached_property
1022 def _reverse_one_to_one_field_names(self):
1023 """
1024 Return a set of reverse one to one field names pointing to the current
1025 model.
1026 """
1027 return frozenset(
1028 field.name for field in self.related_objects if field.one_to_one
1029 )
1030
1031 @cached_property
1032 def db_returning_fields(self):
1033 """
1034 Private API intended only to be used by Django itself.
1035 Fields to be returned after a database insert.
1036 """
1037 return [
1038 field
1039 for field in self._get_fields(
1040 forward=True, reverse=False, include_parents=PROXY_PARENTS
1041 )
1042 if getattr(field, "db_returning", False)
1043 ]