Skip to content
Snippets Groups Projects
Commit 6789d0c7 authored by Nadja Geisler's avatar Nadja Geisler :sunny:
Browse files

Merge branch 'improve-queries' into 'main'

Optimize queries

See merge request !156
parents efecf354 fc824911
No related branches found
No related tags found
No related merge requests found
...@@ -18,7 +18,7 @@ class DashboardView(TemplateView): ...@@ -18,7 +18,7 @@ class DashboardView(TemplateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context['events'] = Event.objects.filter(public=True) context['events'] = Event.objects.filter(public=True).prefetch_related('dashboardbutton_set')
return context return context
...@@ -54,7 +54,7 @@ class DashboardEventView(DetailView): ...@@ -54,7 +54,7 @@ class DashboardEventView(DetailView):
# Changes in plan # Changes in plan
if apps.is_installed("AKPlan"): if apps.is_installed("AKPlan"):
if not context['event'].plan_hidden: if not context['event'].plan_hidden:
last_changed_slots = AKSlot.objects.filter(event=context['event'], start__isnull=False).order_by('-updated')[ last_changed_slots = AKSlot.objects.select_related('ak').filter(event=context['event'], start__isnull=False).order_by('-updated')[
:int(settings.DASHBOARD_RECENT_MAX)] :int(settings.DASHBOARD_RECENT_MAX)]
for changed_slot in last_changed_slots: for changed_slot in last_changed_slots:
recent_changes.append({'icon': ('clock', 'far'), recent_changes.append({'icon': ('clock', 'far'),
......
...@@ -84,14 +84,14 @@ class Event(models.Model): ...@@ -84,14 +84,14 @@ class Event(models.Model):
:return: list of category-AK-list-tuples, optionally the additional list of AK wishes :return: list of category-AK-list-tuples, optionally the additional list of AK wishes
:rtype: list[(AKCategory, list[AK])] [, list[AK]] :rtype: list[(AKCategory, list[AK])] [, list[AK]]
""" """
categories = self.akcategory_set.all() categories = self.akcategory_set.select_related('event').all()
categories_with_aks = [] categories_with_aks = []
ak_wishes = [] ak_wishes = []
if wishes_seperately: if wishes_seperately:
for category in categories: for category in categories:
ak_list = [] ak_list = []
for ak in category.ak_set.all(): for ak in category.ak_set.select_related('event').prefetch_related('owners', 'akslot_set').all():
if filter(ak): if filter(ak):
if ak.wish: if ak.wish:
ak_wishes.append(ak) ak_wishes.append(ak)
...@@ -211,6 +211,9 @@ class AKTrack(models.Model): ...@@ -211,6 +211,9 @@ class AKTrack(models.Model):
def __str__(self): def __str__(self):
return self.name return self.name
def aks_with_category(self):
return self.ak_set.select_related('category').all()
class AKRequirement(models.Model): class AKRequirement(models.Model):
""" An AKRequirement describes something needed to hold an AK, e.g. infrastructure. """ An AKRequirement describes something needed to hold an AK, e.g. infrastructure.
...@@ -291,7 +294,7 @@ class AK(models.Model): ...@@ -291,7 +294,7 @@ class AK(models.Model):
@property @property
def details(self): def details(self):
from AKModel.availability.models import Availability from AKModel.availability.models import Availability
availabilities = ', \n'.join(f'{a.simplified}' for a in Availability.objects.filter(ak=self)) availabilities = ', \n'.join(f'{a.simplified}' for a in Availability.objects.select_related('event').filter(ak=self))
return f"""{self.name}{" (R)" if self.reso else ""}: return f"""{self.name}{" (R)" if self.reso else ""}:
{self.owners_list} {self.owners_list}
...@@ -307,7 +310,7 @@ class AK(models.Model): ...@@ -307,7 +310,7 @@ class AK(models.Model):
@property @property
def durations_list(self): def durations_list(self):
return ", ".join(str(slot.duration_simplified) for slot in self.akslot_set.all()) return ", ".join(str(slot.duration_simplified) for slot in self.akslot_set.select_related('event').all())
@property @property
def wish(self): def wish(self):
...@@ -590,7 +593,7 @@ class ConstraintViolation(models.Model): ...@@ -590,7 +593,7 @@ class ConstraintViolation(models.Model):
@property @property
def _ak_slots_str(self): def _ak_slots_str(self):
if self.pk and self.pk > 0: if self.pk and self.pk > 0:
return ', '.join(str(a) for a in self.ak_slots.all()) return ', '.join(str(a) for a in self.ak_slots.select_related('event').all())
return ', '.join(str(a) for a in self.ak_slots_tmp) return ', '.join(str(a) for a in self.ak_slots_tmp)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
......
...@@ -36,7 +36,7 @@ class EventsView(LoginRequiredMixin, EventSlugMixin, ListView): ...@@ -36,7 +36,7 @@ class EventsView(LoginRequiredMixin, EventSlugMixin, ListView):
model = AKSlot model = AKSlot
def get_queryset(self): def get_queryset(self):
return super().get_queryset().filter(event=self.event, room__isnull=False) return super().get_queryset().select_related('ak').filter(event=self.event, room__isnull=False)
def render_to_response(self, context, **response_kwargs): def render_to_response(self, context, **response_kwargs):
return JsonResponse( return JsonResponse(
...@@ -149,4 +149,4 @@ class ConstraintViolationsViewSet(EventSlugMixin, viewsets.ModelViewSet): ...@@ -149,4 +149,4 @@ class ConstraintViolationsViewSet(EventSlugMixin, viewsets.ModelViewSet):
return get_object_or_404(ConstraintViolation, pk=self.kwargs["pk"]) return get_object_or_404(ConstraintViolation, pk=self.kwargs["pk"])
def get_queryset(self): def get_queryset(self):
return ConstraintViolation.objects.filter(event=self.event).order_by('manually_resolved', '-type', '-timestamp') return ConstraintViolation.objects.select_related('event', 'room').prefetch_related('aks', 'ak_slots', 'ak_owner', 'requirement', 'category').filter(event=self.event).order_by('manually_resolved', '-type', '-timestamp')
...@@ -228,7 +228,7 @@ ...@@ -228,7 +228,7 @@
</div> </div>
<div class="card-body"> <div class="card-body">
<ul data-track-id="{{ track.pk }}" data-name="{{ track }}" data-sync="true" class="ak-list"> <ul data-track-id="{{ track.pk }}" data-name="{{ track }}" data-sync="true" class="ak-list">
{% for ak in track.ak_set.all %} {% for ak in track.aks_with_category %}
<li data-ak-id="{{ ak.pk }}" data-toggle="tooltip" data-placement="top" title=""> <li data-ak-id="{{ ak.pk }}" data-toggle="tooltip" data-placement="top" title="">
{{ ak.name }} ({{ ak.category }}) {{ ak.name }} ({{ ak.category }})
</li> </li>
......
...@@ -31,7 +31,7 @@ class SchedulingAdminView(AdminViewMixin, FilterByEventSlugMixin, ListView): ...@@ -31,7 +31,7 @@ class SchedulingAdminView(AdminViewMixin, FilterByEventSlugMixin, ListView):
context_object_name = "slots_unscheduled" context_object_name = "slots_unscheduled"
def get_queryset(self): def get_queryset(self):
return super().get_queryset().filter(start__isnull=True).select_related().order_by('ak__track') return super().get_queryset().filter(start__isnull=True).select_related('event', 'ak').order_by('ak__track')
def get_context_data(self, *, object_list=None, **kwargs): def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(object_list=object_list, **kwargs) context = super().get_context_data(object_list=object_list, **kwargs)
...@@ -53,7 +53,7 @@ class TrackAdminView(AdminViewMixin, FilterByEventSlugMixin, ListView): ...@@ -53,7 +53,7 @@ class TrackAdminView(AdminViewMixin, FilterByEventSlugMixin, ListView):
def get_context_data(self, *, object_list=None, **kwargs): def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(object_list=object_list, **kwargs) context = super().get_context_data(object_list=object_list, **kwargs)
context["aks_without_track"] = self.event.ak_set.filter(track=None) context["aks_without_track"] = self.event.ak_set.select_related('category').filter(track=None)
return context return context
...@@ -129,10 +129,10 @@ class InterestEnteringAdminView(SuccessMessageMixin, AdminViewMixin, EventSlugMi ...@@ -129,10 +129,10 @@ class InterestEnteringAdminView(SuccessMessageMixin, AdminViewMixin, EventSlugMi
# Find other AK wishes (regardless of the category)... # Find other AK wishes (regardless of the category)...
if context['ak'].wish: if context['ak'].wish:
other_aks = [ak for ak in context['event'].ak_set.all() if ak.wish] other_aks = [ak for ak in context['event'].ak_set.prefetch_related('owners').all() if ak.wish]
# or other AKs of this category # or other AKs of this category
else: else:
other_aks = [ak for ak in context['ak'].category.ak_set.all() if not ak.wish] other_aks = [ak for ak in context['ak'].category.ak_set.prefetch_related('owners').all() if not ak.wish]
for other_ak in other_aks: for other_ak in other_aks:
if next_is_next: if next_is_next:
...@@ -143,9 +143,9 @@ class InterestEnteringAdminView(SuccessMessageMixin, AdminViewMixin, EventSlugMi ...@@ -143,9 +143,9 @@ class InterestEnteringAdminView(SuccessMessageMixin, AdminViewMixin, EventSlugMi
next_is_next = True next_is_next = True
last_ak = other_ak last_ak = other_ak
for category in context['event'].akcategory_set.all(): for category in context['event'].akcategory_set.prefetch_related('ak_set').all():
aks_for_category = [] aks_for_category = []
for ak in category.ak_set.all(): for ak in category.ak_set.prefetch_related('owners').all():
if ak.wish: if ak.wish:
ak_wishes.append(ak) ak_wishes.append(ak)
else: else:
......
...@@ -32,7 +32,7 @@ class AKOverviewView(FilterByEventSlugMixin, ListView): ...@@ -32,7 +32,7 @@ class AKOverviewView(FilterByEventSlugMixin, ListView):
wishes_as_category = False wishes_as_category = False
def filter_aks(self, context, category): def filter_aks(self, context, category):
return category.ak_set.all() return category.ak_set.select_related('event').prefetch_related('owners').all()
def get_active_category_name(self, context): def get_active_category_name(self, context):
return context["categories_with_aks"][0][0].name return context["categories_with_aks"][0][0].name
...@@ -126,6 +126,9 @@ class AKDetailView(EventSlugMixin, DetailView): ...@@ -126,6 +126,9 @@ class AKDetailView(EventSlugMixin, DetailView):
context_object_name = "ak" context_object_name = "ak"
template_name = "AKSubmission/ak_detail.html" template_name = "AKSubmission/ak_detail.html"
def get_queryset(self):
return super().get_queryset().select_related('event').prefetch_related('owners')
def get_context_data(self, *, object_list=None, **kwargs): def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(object_list=object_list, **kwargs) context = super().get_context_data(object_list=object_list, **kwargs)
context["availabilities"] = Availability.objects.filter(ak=context["ak"]) context["availabilities"] = Availability.objects.filter(ak=context["ak"])
...@@ -136,7 +139,7 @@ class AKDetailView(EventSlugMixin, DetailView): ...@@ -136,7 +139,7 @@ class AKDetailView(EventSlugMixin, DetailView):
context["featured_slot_type"] = "NONE" context["featured_slot_type"] = "NONE"
if apps.is_installed("AKPlan"): if apps.is_installed("AKPlan"):
in_two_hours = current_timestamp + timedelta(hours=2) in_two_hours = current_timestamp + timedelta(hours=2)
slots = context["ak"].akslot_set.filter(start__isnull=False, room__isnull=False) slots = context["ak"].akslot_set.filter(start__isnull=False, room__isnull=False).select_related('room')
for slot in slots: for slot in slots:
if slot.end > current_timestamp: if slot.end > current_timestamp:
if slot.start <= current_timestamp: if slot.start <= current_timestamp:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment