Skip to content

Commit 268f1fa

Browse files
committed
[change] Modified existing queries for better readability
The queries for fetching the templates with sorted in `get_relevant_templates` via Subquery, while were working, were a bit complex to understand for future. Fetching templates using config/devicegroup maintains sorting, making the fetching query much readable. Signed-off-by: DragnEmperor <dragnemperor@gmail.com>
1 parent 4f85589 commit 268f1fa

1 file changed

Lines changed: 23 additions & 37 deletions

File tree

openwisp_controller/config/views.py

Lines changed: 23 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
from copy import deepcopy
33
from uuid import UUID
44

5-
from django.db import models as django_models
65
from django.db.models import Q
7-
from django.db.models.functions import Coalesce
86
from django.http import HttpResponse, JsonResponse
97
from django.utils import timezone
108
from 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

Comments
 (0)