22from copy import deepcopy
33from uuid import UUID
44
5- from django .db import models as django_models
65from django .db .models import Q
7- from django .db .models .functions import Coalesce
86from django .http import HttpResponse , JsonResponse
97from django .utils import timezone
108from django .utils .module_loading import import_string
@@ -39,7 +37,6 @@ def get_relevant_templates(request, organization_id):
3937 ):
4038 return HttpResponse (status = 403 )
4139
42- # TODO: do we skip all these checks if user is superuser?
4340 if organization_id :
4441 org = get_object_or_404 (Organization , pk = organization_id , is_active = True )
4542 org_filters = Q (organization_id = org .pk )
@@ -58,54 +55,43 @@ def get_relevant_templates(request, organization_id):
5855 filter_options .update (backend = backend )
5956 else :
6057 filter_options .update (required = False , default = False )
61- sort_value_subquery = through_model = None
62- # fetch the selected templates for the device or group by creating a subquery.
63- # through_model and lookup_field are set based on the presence of device_id or
64- # group_id. we need through_model as `sort_value` is a field of the through model.
65- # the subquery will be used to annotate the queryset with the sort_value
66- # of the selected templates.
67- if device_id and (lookup := Config .objects .filter (device_id = device_id ).first ()):
68- through_model = Config .templates .through
69- lookup_field = "config_id"
70- if group_id and (
71- lookup := DeviceGroup .objects .filter (Q (pk = group_id ) & (org_filters )).first ()
72- ):
73- through_model = DeviceGroup .templates .through
74- lookup_field = "devicegroup_id"
75- # fetch selected templates only if device or group exists
76- if device_id or group_id and through_model :
77- sort_value_subquery = django_models .Subquery (
78- through_model .objects .filter (
79- ** {lookup_field : lookup .id }, template_id = django_models .OuterRef ('pk' )
80- ).values ('sort_value' )[:1 ],
81- output_field = django_models .IntegerField (),
82- )
83- # annotated a selected field which is True based on sort_value
84- # if sort_value is 9999 then selected is False else True
58+
8559 queryset = (
8660 Template .objects .filter (** filter_options )
8761 .filter (org_filters )
88- .annotate (
89- sort_value = Coalesce (sort_value_subquery , django_models .Value (9999 )),
90- selected = django_models .Case (
91- django_models .When (sort_value = 9999 , then = django_models .Value (False )),
92- default = django_models .Value (True ),
93- output_field = django_models .BooleanField (),
94- ),
95- )
96- .order_by ('sort_value' )
9762 .only ('id' , 'name' , 'backend' , 'default' , 'required' )
9863 )
64+ selected_templates = []
65+ if device_id :
66+ selected_templates = (
67+ Config .templates .through .objects .filter (config__device_id = device_id )
68+ .order_by ("sort_value" )
69+ .values_list ("template_id" , flat = True )
70+ )
71+ if group_id :
72+ selected_templates = DeviceGroup .templates .through .objects .filter (
73+ devicegroup_id = group_id , devicegroup__organization_id = organization_id
74+ ).values_list ('template_id' , flat = True )
9975
76+ selected_templates = [str (template ) for template in selected_templates ]
10077 relevant_templates = {}
10178 for template in queryset :
10279 relevant_templates [str (template .pk )] = dict (
10380 name = template .name ,
10481 backend = template .get_backend_display (),
10582 default = template .default ,
10683 required = template .required ,
107- selected = template .selected ,
84+ selected = str (template .pk ) in selected_templates ,
85+ )
86+ # sort based on order of selected_templates
87+ relevant_templates = dict (
88+ sorted (
89+ relevant_templates .items (),
90+ key = lambda item : selected_templates .index (item [0 ])
91+ if item [0 ] in selected_templates
92+ else len (selected_templates ),
10893 )
94+ )
10995 return JsonResponse (relevant_templates )
11096
11197
0 commit comments