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.