Return whether `field` should be used to descend deeper for `select_related()` purposes. Arguments: * `field` - the field to be checked. Can be either a `Field` or `ForeignObjectRel` instance. * `restricted` - a boolean field, indicating if the field list has been
(field, restricted, requested, select_mask)
| 429 | |
| 430 | |
| 431 | def select_related_descend(field, restricted, requested, select_mask): |
| 432 | """ |
| 433 | Return whether `field` should be used to descend deeper for |
| 434 | `select_related()` purposes. |
| 435 | |
| 436 | Arguments: |
| 437 | * `field` - the field to be checked. Can be either a `Field` or |
| 438 | `ForeignObjectRel` instance. |
| 439 | * `restricted` - a boolean field, indicating if the field list has been |
| 440 | manually restricted using a select_related() clause. |
| 441 | * `requested` - the select_related() dictionary. |
| 442 | * `select_mask` - the dictionary of selected fields. |
| 443 | """ |
| 444 | # Only relationships can be descended. |
| 445 | if not field.remote_field: |
| 446 | return False |
| 447 | # Forward MTI parent links should not be explicitly descended as they are |
| 448 | # always JOIN'ed against (unless excluded by `select_mask`). |
| 449 | if getattr(field.remote_field, "parent_link", False): |
| 450 | return False |
| 451 | # When `select_related()` is used without a `*requested` mask all |
| 452 | # relationships are descended unless they are nullable. |
| 453 | if not restricted: |
| 454 | return not field.null |
| 455 | # When `select_related(*requested)` is used only fields that are part of |
| 456 | # `requested` should be descended. |
| 457 | if field.name not in requested: |
| 458 | return False |
| 459 | # Prevent invalid usages of `select_related()` and `only()`/`defer()` such |
| 460 | # as `select_related("a").only("b")` and `select_related("a").defer("a")`. |
| 461 | if select_mask and field not in select_mask: |
| 462 | raise FieldError( |
| 463 | f"Field {field.model._meta.object_name}.{field.name} cannot be both " |
| 464 | "deferred and traversed using select_related at the same time." |
| 465 | ) |
| 466 | return True |
| 467 | |
| 468 | |
| 469 | def refs_expression(lookup_parts, annotations): |
no test coverage detected