From 5549d48e1ace52fa15ae104f8801c7fc368305d8 Mon Sep 17 00:00:00 2001 From: Birger Schacht Date: Thu, 21 Mar 2024 14:36:42 +0100 Subject: [PATCH] refactor(utils): use contenttype instead of model name for helper The `get_classes_with_allowed_relation_from` method created a list of possible related models based on the name of one model. It then returned the names of those models as strings. It makes more sense to simply use contenttypes instead of model names, especially since the Property model stores the possible subj and obj classes as ContentTypes. This commit refactors the method and also updates `triple_sidebar` which is the only function that uses the `get_classes_with_allowed_relation_from` method. Closes: #254 --- .../templatetags/apis_templatetags.py | 4 +- .../templatetags/apis_history_templatetags.py | 4 +- apis_core/history/utils.py | 34 +++++++------- apis_core/utils/helpers.py | 46 +++++++++---------- 4 files changed, 40 insertions(+), 48 deletions(-) diff --git a/apis_core/apis_entities/templatetags/apis_templatetags.py b/apis_core/apis_entities/templatetags/apis_templatetags.py index f64f48cd0..559b2359c 100644 --- a/apis_core/apis_entities/templatetags/apis_templatetags.py +++ b/apis_core/apis_entities/templatetags/apis_templatetags.py @@ -53,6 +53,4 @@ def entities_verbose_name_plural_listview_url(): @register.simple_tag(takes_context=True) def object_relations(context, detail=True): obj = context["object"] - return triple_sidebar( - obj.pk, obj.__class__.__name__.lower(), context["request"], detail - ) + return triple_sidebar(obj, context["request"], detail) diff --git a/apis_core/history/templatetags/apis_history_templatetags.py b/apis_core/history/templatetags/apis_history_templatetags.py index 911b5f9cb..2639e484d 100644 --- a/apis_core/history/templatetags/apis_history_templatetags.py +++ b/apis_core/history/templatetags/apis_history_templatetags.py @@ -10,9 +10,7 @@ @register.simple_tag(takes_context=True) def object_relations_history(context, detail=True): obj = context["object"] - return triple_sidebar_history( - obj.pk, obj.__class__.__name__.lower(), context["request"], detail - ) + return triple_sidebar_history(obj, context["request"], detail) @register.filter diff --git a/apis_core/history/utils.py b/apis_core/history/utils.py index 856ee2bb3..6bdf4cf5e 100644 --- a/apis_core/history/utils.py +++ b/apis_core/history/utils.py @@ -1,19 +1,21 @@ from apis_core.apis_relations.tables import get_generic_triple_table -from apis_core.utils.helpers import get_classes_with_allowed_relation_from +from apis_core.utils.helpers import get_content_types_with_allowed_relation_from from apis_core.utils.settings import get_entity_settings_by_modelname from django.contrib.contenttypes.models import ContentType from django.db.models import Q from django_tables2 import RequestConfig +from simple_history.utils import get_history_model_for_model -def triple_sidebar_history(pk: int, entity_name: str, request, detail=True): +def triple_sidebar_history(obj: object, request, detail=True): + content_type = ContentType.objects.get_for_model(obj) side_bar = [] - entity_name = entity_name.replace("version", "") + history_model = get_history_model_for_model(obj) historical_entity = ( - ContentType.objects.get(model=entity_name) + ContentType.objects.get(model=history_model) .model_class() - .history.get(history_id=pk) + .history.get(history_id=obj.pk) ) triples_related_all = historical_entity.get_triples_for_version() if historical_entity.version_tag is not None: @@ -23,30 +25,28 @@ def triple_sidebar_history(pk: int, entity_name: str, request, detail=True): ) pk = historical_entity.instance.pk - for entity_class in get_classes_with_allowed_relation_from(entity_name): - entity_content_type = ContentType.objects.get_for_model(entity_class) - - other_entity_class_name = entity_class.__name__.lower() - + for other_content_type in get_content_types_with_allowed_relation_from( + content_type + ): triples_related_by_entity = triples_related_all.filter( - (Q(subj__self_contenttype=entity_content_type) & Q(obj__pk=pk)) - | (Q(obj__self_contenttype=entity_content_type) & Q(subj__pk=pk)) + (Q(subj__self_contenttype=other_content_type) & Q(obj__pk=obj.pk)) + | (Q(obj__self_contenttype=other_content_type) & Q(subj__pk=obj.pk)) ) table_class = get_generic_triple_table( - other_entity_class_name=other_entity_class_name, + other_entity_class_name=other_content_type.model, entity_pk_self=pk, detail=detail, ) - prefix = f"{other_entity_class_name}" - title_card = prefix + prefix = f"{other_content_type.model}" + title_card = other_content_type.name tb_object = table_class(data=triples_related_by_entity, prefix=prefix) tb_object_open = request.GET.get(prefix + "page", None) - entity_settings = get_entity_settings_by_modelname(entity_class.__name__) + entity_settings = get_entity_settings_by_modelname(content_type.model) per_page = entity_settings.get("relations_per_page", 10) RequestConfig(request, paginate={"per_page": per_page}).configure(tb_object) - tab_id = f"triple_form_{entity_name}_to_{other_entity_class_name}" + tab_id = f"triple_form_{content_type.model}_to_{other_content_type.model}" side_bar.append( ( title_card, diff --git a/apis_core/utils/helpers.py b/apis_core/utils/helpers.py index 9f5a40553..9b16b585a 100644 --- a/apis_core/utils/helpers.py +++ b/apis_core/utils/helpers.py @@ -19,17 +19,17 @@ from django_tables2 import RequestConfig -def get_classes_with_allowed_relation_from( - entity_name: str, -) -> list[object]: - """Returns a list of classes to which the given class may be related by a Property""" +def get_content_types_with_allowed_relation_from( + content_type: ContentType, +) -> list[ContentType]: + """Returns a list of ContentTypes to which the given ContentTypes may be related by a Property""" # Find all the properties where the entity is either subject or object properties_with_entity_as_subject = Property.objects.filter( - subj_class__model=entity_name + subj_class=content_type ).prefetch_related("obj_class") properties_with_entity_as_object = Property.objects.filter( - obj_class__model=entity_name + obj_class=content_type ).prefetch_related("subj_class") content_type_querysets = [] @@ -44,10 +44,7 @@ def get_classes_with_allowed_relation_from( content_type_querysets.append(subjs) # Join querysets with itertools.chain, call set to make unique, and extract the model class - return [ - content_type.model_class() - for content_type in set(itertools.chain(*content_type_querysets)) - ] + return set(itertools.chain(*content_type_querysets)) def get_member_for_entity( @@ -139,39 +136,38 @@ def datadump_serializer(additional_app_labels: list = [], serialier_format="json ) -def triple_sidebar(pk: int, entity_name: str, request, detail=True): +def triple_sidebar(obj: object, request, detail=True): + content_type = ContentType.objects.get_for_model(obj) side_bar = [] triples_related_all = ( - TempTriple.objects_inheritance.filter(Q(subj__pk=pk) | Q(obj__pk=pk)) + TempTriple.objects_inheritance.filter(Q(subj__pk=obj.pk) | Q(obj__pk=obj.pk)) .all() .select_subclasses() ) - for entity_class in get_classes_with_allowed_relation_from(entity_name): - entity_content_type = ContentType.objects.get_for_model(entity_class) - - other_entity_class_name = entity_class.__name__.lower() - + for other_content_type in get_content_types_with_allowed_relation_from( + content_type + ): triples_related_by_entity = triples_related_all.filter( - (Q(subj__self_contenttype=entity_content_type) & Q(obj__pk=pk)) - | (Q(obj__self_contenttype=entity_content_type) & Q(subj__pk=pk)) + (Q(subj__self_contenttype=other_content_type) & Q(obj__pk=obj.pk)) + | (Q(obj__self_contenttype=other_content_type) & Q(subj__pk=obj.pk)) ) table_class = get_generic_triple_table( - other_entity_class_name=other_entity_class_name, - entity_pk_self=pk, + other_entity_class_name=other_content_type.model, + entity_pk_self=obj.pk, detail=detail, ) - prefix = f"{other_entity_class_name}" - title_card = entity_class._meta.verbose_name + prefix = f"{other_content_type.model}" + title_card = other_content_type.name tb_object = table_class(data=triples_related_by_entity, prefix=prefix) tb_object_open = request.GET.get(prefix + "page", None) - entity_settings = get_entity_settings_by_modelname(entity_class.__name__) + entity_settings = get_entity_settings_by_modelname(content_type.model) per_page = entity_settings.get("relations_per_page", 10) RequestConfig(request, paginate={"per_page": per_page}).configure(tb_object) - tab_id = f"triple_form_{entity_name}_to_{other_entity_class_name}" + tab_id = f"triple_form_{content_type.model}_to_{other_content_type.model}" side_bar.append( ( title_card,