authentik.lib.utils.inheritance

 1from django.db.models import Model, OneToOneField, OneToOneRel
 2
 3
 4def get_deepest_child(parent: Model) -> Model:
 5    """
 6    In multiple table inheritance, given any ancestor object, get the deepest child object.
 7    See https://docs.djangoproject.com/en/dev/topics/db/models/#multi-table-inheritance
 8
 9    This function does not query the database if `select_related` has been performed on all
10    subclasses of `parent`'s model.
11    """
12
13    # Almost verbatim copy from django-model-utils, see
14    # https://github.com/jazzband/django-model-utils/blob/5.0.0/model_utils/managers.py#L132
15    one_to_one_rels = [
16        field for field in parent._meta.get_fields() if isinstance(field, OneToOneRel)
17    ]
18
19    submodel_fields = [
20        rel
21        for rel in one_to_one_rels
22        if isinstance(rel.field, OneToOneField)
23        and issubclass(rel.field.model, parent._meta.model)
24        and parent._meta.model is not rel.field.model
25        and rel.parent_link
26    ]
27
28    submodel_accessors = [submodel_field.get_accessor_name() for submodel_field in submodel_fields]
29    # End Copy
30
31    child = None
32    for submodel in submodel_accessors:
33        try:
34            child = getattr(parent, submodel)
35            break
36        except AttributeError:
37            continue
38
39    if not child:
40        return parent
41    return get_deepest_child(child)
def get_deepest_child(parent: django.db.models.base.Model) -> django.db.models.base.Model:
 5def get_deepest_child(parent: Model) -> Model:
 6    """
 7    In multiple table inheritance, given any ancestor object, get the deepest child object.
 8    See https://docs.djangoproject.com/en/dev/topics/db/models/#multi-table-inheritance
 9
10    This function does not query the database if `select_related` has been performed on all
11    subclasses of `parent`'s model.
12    """
13
14    # Almost verbatim copy from django-model-utils, see
15    # https://github.com/jazzband/django-model-utils/blob/5.0.0/model_utils/managers.py#L132
16    one_to_one_rels = [
17        field for field in parent._meta.get_fields() if isinstance(field, OneToOneRel)
18    ]
19
20    submodel_fields = [
21        rel
22        for rel in one_to_one_rels
23        if isinstance(rel.field, OneToOneField)
24        and issubclass(rel.field.model, parent._meta.model)
25        and parent._meta.model is not rel.field.model
26        and rel.parent_link
27    ]
28
29    submodel_accessors = [submodel_field.get_accessor_name() for submodel_field in submodel_fields]
30    # End Copy
31
32    child = None
33    for submodel in submodel_accessors:
34        try:
35            child = getattr(parent, submodel)
36            break
37        except AttributeError:
38            continue
39
40    if not child:
41        return parent
42    return get_deepest_child(child)

In multiple table inheritance, given any ancestor object, get the deepest child object. See https://docs.djangoproject.com/en/dev/topics/db/models/#multi-table-inheritance

This function does not query the database if select_related has been performed on all subclasses of parent's model.