Much prefetch/select related optimisations

This commit is contained in:
2021-02-08 18:18:16 +00:00
parent 603e919ad0
commit 3f93cebf41
8 changed files with 32 additions and 20 deletions

View File

@@ -166,16 +166,17 @@ class InvoiceWaiting(generic.ListView):
def get_context_data(self, **kwargs):
context = super(InvoiceWaiting, self).get_context_data(**kwargs)
total = 0
for obj in self.get_objects():
objects = self.get_queryset()
for obj in objects:
total += obj.sum_total
context['page_title'] = "Events for Invoice ({} Events, £{:.2f})".format(len(self.get_objects()), total)
context['page_title'] = "Events for Invoice ({} Events, £{:.2f})".format(len(objects), total)
return context
def get_queryset(self):
return self.get_objects()
def get_objects(self):
# @todo find a way to select items
# TODO find a way to select items
events = self.model.objects.filter(
(
Q(start_date__lte=datetime.date.today(), end_date__isnull=True) | # Starts before with no end

View File

@@ -76,6 +76,9 @@ class EventRiskAssessmentList(generic.ListView):
model = models.RiskAssessment
template_name = 'hs_object_list.html'
def get_queryset(self):
return self.model.objects.order_by('reviewed_at').select_related('event')
def get_context_data(self, **kwargs):
context = super(EventRiskAssessmentList, self).get_context_data(**kwargs)
context['title'] = 'Risk Assessment'
@@ -83,7 +86,6 @@ class EventRiskAssessmentList(generic.ListView):
context['edit'] = 'ra_edit'
context['review'] = 'ra_review'
context['perm'] = 'perms.RIGS.review_riskassessment'
context['fields'] = [n.name for n in list(self.model._meta.get_fields()) if n.name != 'reviewed_at' and n.name != 'reviewed_by' and not n.is_relation and not n.auto_created]
return context
@@ -187,7 +189,6 @@ class EventChecklistList(generic.ListView):
context['edit'] = 'ec_edit'
context['review'] = 'ec_review'
context['perm'] = 'perms.RIGS.review_eventchecklist'
context['fields'] = [n.name for n in list(self.model._meta.get_fields()) if n.name != 'reviewed_at' and n.name != 'reviewed_by' and not n.is_relation and not n.auto_created]
return context
@@ -209,7 +210,7 @@ class HSList(generic.ListView):
template_name = 'hs_list.html'
def get_queryset(self):
return models.Event.objects.all().order_by('-start_date')
return models.Event.objects.all().order_by('-start_date').select_related('riskassessment').prefetch_related('checklists')
def get_context_data(self, **kwargs):
context = super(HSList, self).get_context_data(**kwargs)

View File

@@ -52,7 +52,7 @@ class Profile(AbstractUser):
@property
def latest_events(self):
return self.event_mic.order_by('-start_date').select_related('person', 'organisation', 'venue', 'mic')
return self.event_mic.order_by('-start_date').select_related('person', 'organisation', 'venue', 'mic', 'riskassessment', 'invoice').prefetch_related('checklists')
@classmethod
def admins(cls):
@@ -244,7 +244,7 @@ class EventManager(models.Manager):
(models.Q(dry_hire=True, checked_in_by__isnull=True) & (
models.Q(status=Event.BOOKED) | models.Q(status=Event.CONFIRMED))) | # Active dry hire GT
models.Q(status=Event.CANCELLED, start_date__gte=timezone.now()) # Canceled but not started
).order_by('start_date', 'end_date', 'start_time', 'end_time', 'meet_at').select_related('person', 'organisation', 'venue', 'mic', 'riskassessment', 'invoice').prefetch_related('checklists')
).order_by('start_date', 'end_date', 'start_time', 'end_time', 'meet_at').select_related('person', 'organisation', 'venue', 'mic')
return events
@@ -345,7 +345,7 @@ class Event(models.Model, RevisionMixin):
@property
def sum_total(self):
total = EventItem.objects.filter(event=self).aggregate(
total = self.items.aggregate(
sum_total=models.Sum(models.F('cost') * models.F('quantity'),
output_field=models.DecimalField(max_digits=10, decimal_places=2))
)['sum_total']
@@ -706,6 +706,10 @@ class RiskAssessment(models.Model, RevisionMixin):
('review_riskassessment', 'Can review Risk Assessments')
]
@cached_property
def fields(self):
return [n.name for n in list(self._meta.get_fields()) if n.name != 'reviewed_at' and n.name != 'reviewed_by' and not n.is_relation and not n.auto_created]
@property
def event_size(self):
# Confirm event size. Check all except generators, since generators entails outside
@@ -788,6 +792,10 @@ class EventChecklist(models.Model, RevisionMixin):
inverted_fields = []
@cached_property
def fields(self):
return [n.name for n in list(self.model._meta.get_fields()) if n.name != 'reviewed_at' and n.name != 'reviewed_by' and not n.is_relation and not n.auto_created]
class Meta:
ordering = ['event']
permissions = [

View File

@@ -41,7 +41,7 @@ class RigboardIndex(generic.TemplateView):
context = super(RigboardIndex, self).get_context_data(**kwargs)
# call out method to get current events
context['events'] = models.Event.objects.current_events()
context['events'] = models.Event.objects.current_events().select_related('riskassessment', 'invoice').prefetch_related('checklists')
context['page_title'] = "Rigboard"
return context

View File

@@ -21,7 +21,7 @@
<th scope="col">Event</th>
{# mmm hax #}
{% if object_list.0 != None %}
{% for field in fields %}
{% for field in object_list.0.fields %}
<th scope="col">{{ object_list.0|verbose_name:field|title }}</th>
{% endfor %}
{% endif %}
@@ -33,7 +33,7 @@
<tr class="{% if object.reviewed_by %}table-success{%endif%}">
{# General #}
<th scope="row"><a href="{% url 'event_detail' object.event.pk %}">{{ object.event }}</a></th>
{% for field in fields %}
{% for field in object_list.0.fields %}
<td>{{ object|get_field:field }}</td>
{% endfor %}
{# Buttons #}

View File

@@ -42,7 +42,7 @@
<td>{{ invoice.event.start_date }}</td>
<td>{{ invoice.invoice_date }}</td>
<td>
{{ invoice.balance|floatformat:2 }}
£{{ invoice.balance|floatformat:2 }}
{% if not invoice.event.internal %}
<br />
<span class="text-muted">{{ invoice.event.purchase_order }}</span>

View File

@@ -53,7 +53,7 @@
{% endif %}
</td>
<td>
{{ event.sum_total|floatformat:2 }}
£{{ event.sum_total|floatformat:2 }}
<br />
<span class="text-muted">{% if not event.internal %}{{ event.purchase_order }}{% endif %}</span>
</td>

View File

@@ -39,12 +39,12 @@ class AssetList(LoginRequiredMixin, generic.ListView):
# TODO Feedback to user when search fails
query_string = form.cleaned_data['q'] or ""
if len(query_string) == 0:
queryset = self.model.objects.all().select_related('category', 'status')
queryset = self.model.objects.all()
elif len(query_string) >= 3:
queryset = self.model.objects.filter(
Q(asset_id__exact=query_string) | Q(description__icontains=query_string) | Q(serial_number__exact=query_string)).select_related('category', 'status')
Q(asset_id__exact=query_string) | Q(description__icontains=query_string) | Q(serial_number__exact=query_string))
else:
queryset = self.model.objects.filter(Q(asset_id__exact=query_string)).select_related('category', 'status')
queryset = self.model.objects.filter(Q(asset_id__exact=query_string))
if form.cleaned_data['category']:
queryset = queryset.filter(category__in=form.cleaned_data['category'])
@@ -55,7 +55,7 @@ class AssetList(LoginRequiredMixin, generic.ListView):
queryset = queryset.filter(
status__in=models.AssetStatus.objects.filter(should_show=True))
return queryset
return queryset.select_related('category', 'status')
def get_context_data(self, **kwargs):
context = super(AssetList, self).get_context_data(**kwargs)
@@ -180,7 +180,7 @@ class AssetAuditList(AssetList):
# TODO Refresh this when the modal is submitted
def get_queryset(self):
self.form = forms.AssetSearchForm(data=self.request.GET)
return self.model.objects.filter(Q(last_audited_at__isnull=True))
return self.model.objects.filter(Q(last_audited_at__isnull=True)).select_related('category', 'status')
def get_context_data(self, **kwargs):
context = super(AssetAuditList, self).get_context_data(**kwargs)
@@ -288,7 +288,9 @@ class CableTypeList(generic.ListView):
model = models.CableType
template_name = 'cable_type_list.html'
paginate_by = 40
# ordering = ['__str__']
def get_queryset(self):
return self.model.objects.select_related('plug', 'socket')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)