Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.10/site-packages/django/db/models/options.py: 20%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

490 statements  

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 ]