| 435 | |
| 436 | |
| 437 | class LazyReference(DBRef): |
| 438 | __slots__ = ("_cached_doc", "passthrough", "document_type") |
| 439 | |
| 440 | def fetch(self, force=False): |
| 441 | if not self._cached_doc or force: |
| 442 | self._cached_doc = self.document_type.objects.get(pk=self.pk) |
| 443 | if not self._cached_doc: |
| 444 | raise DoesNotExist("Trying to dereference unknown document %s" % (self)) |
| 445 | return self._cached_doc |
| 446 | |
| 447 | @property |
| 448 | def pk(self): |
| 449 | return self.id |
| 450 | |
| 451 | def __init__(self, document_type, pk, cached_doc=None, passthrough=False): |
| 452 | self.document_type = document_type |
| 453 | self._cached_doc = cached_doc |
| 454 | self.passthrough = passthrough |
| 455 | super().__init__(self.document_type._get_collection_name(), pk) |
| 456 | |
| 457 | def __getitem__(self, name): |
| 458 | if not self.passthrough: |
| 459 | raise KeyError() |
| 460 | document = self.fetch() |
| 461 | return document[name] |
| 462 | |
| 463 | def __getattr__(self, name): |
| 464 | if not object.__getattribute__(self, "passthrough"): |
| 465 | raise AttributeError() |
| 466 | document = self.fetch() |
| 467 | try: |
| 468 | return document[name] |
| 469 | except KeyError: |
| 470 | raise AttributeError() |
| 471 | |
| 472 | def __repr__(self): |
| 473 | return f"<LazyReference({self.document_type}, {self.pk!r})>" |
no outgoing calls