1
0
Fork 0

[Fixes #315] Use query annotation instead of model properties to filter Observation faster.

merge-requests/317/head
Scott Bragg 2017-02-24 21:57:19 +11:00
parent 8b25aea781
commit 0d77fd7e44
1 changed files with 29 additions and 10 deletions

View File

@ -18,6 +18,7 @@ from django.utils.text import slugify
from django.views.decorators.http import require_POST
from django.views.decorators.cache import cache_page
from django.views.generic import ListView
from django.db.models import Count, Case, When, F
from rest_framework import serializers, viewsets
@ -173,16 +174,34 @@ class ObservationListView(ListView):
observations = Observation.objects.filter(
satellite__norad_cat_id=norad_cat_id).order_by('-id')
# Good/Bad/Unvetted are properties of the model not fields
# so cannot use queryset filtering
resultset = []
for ob in observations:
if bad and ob.has_no_data:
resultset.append(ob)
elif good and ob.has_verified_data:
resultset.append(ob)
elif unvetted and ob.has_unvetted_data:
resultset.append(ob)
# Add the data subqueries as annotations
observations = observations.annotate(
data_count=Count('data', distinct=True),
nodata_count=Count(
Case(
When(data__vetted_status='no_data', then=1)
), distinct=True
),
unknown_count=Count(
Case(
When(data__vetted_status='unknown', then=1)
), distinct=True
),
vetted_count=Count(
Case(
When(data__vetted_status='verified', then=1)
), distinct=True
)
)
# Start with an empty queryset and add each filter as an or/union
resultset = Observation.objects.none()
if bad:
resultset |= observations.filter(nodata_count=F('data_count'))
if good:
resultset |= observations.filter(vetted_count__gt=0)
if unvetted:
resultset |= observations.filter(unknown_count__gt=0)
return resultset
def get_context_data(self, **kwargs):