Skip to content

Commit

Permalink
reduce number of repeated queries
Browse files Browse the repository at this point in the history
move queries that get favourites and auto converted to methods that
generate dicts hence one query for all rather than one query per data
set
  • Loading branch information
struan committed Jan 11, 2024
1 parent 9d9ae83 commit 9f7f2f2
Showing 1 changed file with 26 additions and 23 deletions.
49 changes: 26 additions & 23 deletions hub/views/area.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from collections import defaultdict

from django.db.models import Count, OuterRef, Subquery
from django.db.models import Count
from django.http import JsonResponse
from django.shortcuts import get_object_or_404, redirect
from django.views.generic import DetailView, TemplateView, View
Expand Down Expand Up @@ -47,23 +47,31 @@ def get_object(self):
def get_page_title(self):
return self.object.name

def process_dataset(self, data_set):
fav_sq = Subquery(
def get_user_favourite_datasets(self):
favs = (
UserDataSets.objects.filter(
data_set_id=OuterRef("data_type__data_set__id"),
user=self.request.user,
)
.values("data_set_id")
.annotate(is_favourite=Count("id"))
.values("is_favourite")
)
data_type = DataType.objects.filter(
data_set=data_set, area_type=self.object.area_type
).first()
auto_converted = False
if data_type is not None:
auto_converted = data_type.auto_converted

fav_map = {}
for fav in favs:
fav_map["fav.data_set_id"] = fav["is_favourite"]

Check warning on line 62 in hub/views/area.py

View check run for this annotation

Codecov / codecov/patch

hub/views/area.py#L62

Added line #L62 was not covered by tests

return fav_map

def get_auto_convered_datasets(self):
auto_converted = {}

for ds in DataType.objects.filter(area_type=self.object.area_type):
auto_converted[ds.data_set_id] = ds.auto_converted

return auto_converted

def process_dataset(self, data_set, favs, auto_converted):
base_qs = AreaData.objects.filter(
area=self.object,
data_type__data_set=data_set,
Expand All @@ -81,33 +89,26 @@ def process_dataset(self, data_set):
"data_type": data_set.data_type,
"featured": data_set.featured,
"excluded_countries": data_set.exclude_countries,
"auto_converted": auto_converted,
"auto_converted": auto_converted.get(data_set.id, False),
"is_favourite": favs.get(data_set.id, False),
}
if data_set.is_range:
data["is_range"] = True
data_range = base_qs.select_related("data_type").order_by("data_type__name")

data["is_favourite"] = UserDataSets.objects.filter(
data_set=data_set,
user=self.request.user,
).exists()
d = data_range.all()
if len(d) == 0:
d = None

data["data"] = d
elif data_set.category == "opinion":
data_range = (
base_qs.annotate(is_favourite=fav_sq)
.select_related("data_type")
.order_by("data_type__order", "data_type__label")
data_range = base_qs.select_related("data_type").order_by(
"data_type__order", "data_type__label"
)

data["data"] = data_range.all()
else:
area_data = base_qs.annotate(is_favourite=fav_sq).select_related(
"data_type"
)
area_data = base_qs.select_related("data_type")
if area_data:
data["data"] = area_data[0]

Expand Down Expand Up @@ -190,10 +191,12 @@ def get_context_data(self, **kwargs):

categories = defaultdict(list)
indexed_categories = defaultdict(dict)
favs = self.get_user_favourite_datasets()
auto_converted = self.get_auto_convered_datasets()
for data_set in DataSet.objects.order_by("order", "label").filter(
areas_available=self.object.area_type
):
data = self.process_dataset(data_set)
data = self.process_dataset(data_set, favs, auto_converted)

if data.get("data", None) is not None and data["data"]:
if data_set.category is not None:
Expand Down

0 comments on commit 9f7f2f2

Please sign in to comment.