Coverage for apis_core/relations/templatetags/relations.py: 44%
41 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-16 07:42 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-16 07:42 +0000
1from django import template
2from django.contrib.contenttypes.models import ContentType
3from django.db.models import Case, Q, Value, When
5from apis_core.generic.helpers import first_member_match, module_paths
6from apis_core.relations.models import Relation
7from apis_core.relations.tables import RelationsListTable
8from apis_core.relations.utils import relation_content_types, relation_match_target
10register = template.Library()
13@register.simple_tag
14def possible_relation_types_from(obj) -> list[ContentType]:
15 return relation_content_types(any_model=type(obj))
18@register.simple_tag
19def get_relation_targets_from(obj) -> list[ContentType]:
20 relations = relation_content_types(any_model=type(obj))
21 types = set()
22 for model in [relation.model_class() for relation in relations]:
23 if type(obj) in model.obj_list():
24 types.update(model.subj_list())
25 if type(obj) in model.subj_list():
26 types.update(model.obj_list())
27 return sorted(
28 list(map(ContentType.objects.get_for_model, types)), key=lambda x: x.name
29 )
32@register.simple_tag
33def relations_from(from_obj, relation_type: ContentType = None):
34 from_content_type = ContentType.objects.get_for_model(from_obj)
35 relation = Relation
36 if relation_type is not None:
37 relation = relation_type.model_class()
39 relations = (
40 relation.objects.filter(
41 Q(subj_content_type=from_content_type, subj_object_id=from_obj.id)
42 | Q(obj_content_type=from_content_type, obj_object_id=from_obj.id)
43 )
44 .annotate(
45 forward=Case(
46 When(
47 subj_content_type=from_content_type,
48 subj_object_id=from_obj.id,
49 then=Value(True),
50 ),
51 default=Value(False),
52 )
53 )
54 .select_subclasses()
55 )
56 return relations
59@register.simple_tag(takes_context=True)
60def relations_list_table(context, relations, target=None):
61 table_modules = module_paths(
62 type(context["object"]),
63 path="tables",
64 suffix=f"{target.name.capitalize()}RelationsTable",
65 )
66 table_class = first_member_match(table_modules, RelationsListTable)
67 if target:
68 relations = [
69 relation
70 for relation in relations
71 if relation_match_target(relation, target)
72 ]
73 return table_class(relations, request=context["request"])
76@register.simple_tag
77def relations_verbose_name_listview_url():
78 """
79 Return all relations verbose names together with their list uri, sorted in alphabetical order
80 USED BY:
81 * `apis_core/relations/templates/base.html` (to extend the default `base.html`)
82 """
83 relation_classes = [relation.model_class() for relation in relation_content_types()]
84 ret = {
85 relation._meta.verbose_name: relation.get_listview_url()
86 for relation in relation_classes
87 }
88 return sorted(ret.items())