Skip to content

Commit

Permalink
Add a route to get subjecs most recent locations.
Browse files Browse the repository at this point in the history
  • Loading branch information
trevor-james-nangosha committed Nov 5, 2024
1 parent 71d1417 commit 4f4c5ee
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 19 deletions.
34 changes: 22 additions & 12 deletions api/admin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from django.contrib import admin
from .models import Subject, Test, Disease, Result
from .models import (
Subject,
Test,
Disease,
Result, Location)

class SubjectAdmin(admin.ModelAdmin):
# control which columns appear in the list view
Expand Down Expand Up @@ -34,10 +38,8 @@ class SubjectAdmin(admin.ModelAdmin):
readonly_fields = ('date_archived', 'date_deleted', 'created_at', 'modified_at')

class TestAdmin(admin.ModelAdmin):
# control which columns appear in the list view
list_display = ('disease_id', 'subject')

# Fields for when adding a user
add_fieldsets = (
(None, {
'classes': ('wide',),
Expand All @@ -47,14 +49,6 @@ class TestAdmin(admin.ModelAdmin):
)}
),
)

# Fields for editing existing users, grouped in fieldsets
# fieldsets = (
# (None, {'fields': ('email', 'password')}),
# ('Personal info', {'fields': ('name',)}),
# ('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}),
# ('Important dates', {'fields': ('last_login', 'date_joined')}),
# )

readonly_fields = ('created_at', 'modified_at')

Expand Down Expand Up @@ -89,9 +83,25 @@ class ResultAdmin(admin.ModelAdmin):
)

readonly_fields = ('created_at', 'modified_at')

class LocationAdmin(admin.ModelAdmin):
list_display = ('id', 'latitude', 'longitude', 'subject')

add_fieldsets = (
(None, {
# 'classes': ('wide',),
'fields': (
'subject',
'latitude',
'longitude'
)}
),
)

readonly_fields = ('created_at', 'modified_at')

admin.site.register(Subject, SubjectAdmin)
admin.site.register(Test, TestAdmin)
admin.site.register(Disease, DiseaseAdmin)
admin.site.register(Result, ResultAdmin)
admin.site.register(Result, ResultAdmin)
admin.site.register(Location, LocationAdmin)
2 changes: 1 addition & 1 deletion api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def create(self, validated_data):
class LocationSerializer(serializers.ModelSerializer):
class Meta:
model = Location
fields = ['latitude', 'longitude', 'user']
fields = ['latitude', 'longitude', 'subject']

class BulkLocationSerializer(serializers.Serializer):
locations = LocationSerializer(many=True)
Expand Down
80 changes: 74 additions & 6 deletions api/views.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import random
from datetime import timedelta

from django.utils import timezone
from django.db.models import F
from django.db.models import F, Subquery, OuterRef, Count
from django.core.paginator import Paginator
from django.db.models.functions import TruncDate

from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.permissions import AllowAny
from rest_framework.decorators import action
from rest_framework.pagination import PageNumberPagination

from rest_framework_simplejwt.tokens import RefreshToken
Expand Down Expand Up @@ -143,6 +148,27 @@ def destroy(self, request, *args, **kwargs):

return Response(status=status.HTTP_204_NO_CONTENT)

def get_subjects_most_recent_locations(self):
latest_locations = Location.objects.filter(
created_at=Subquery(
Location.objects.filter(
subject=OuterRef('subject')
).order_by('-created_at').values('created_at')[:1]
)
).select_related('subject')

return latest_locations

@action(detail=False, methods=['get'], url_path='latest-locations')
def get_subjects_recent_locations(self, request):
locations = self.get_subjects_most_recent_locations()
serializer = LocationSerializer(locations, many=True)

return Response({
'total': locations.count(),
'data': serializer.data
})

class LocationViewSet(viewsets.ModelViewSet):
queryset = Location.objects.filter(date_deleted__isnull=True)
serializer_class = LocationSerializer
Expand Down Expand Up @@ -176,14 +202,56 @@ def destroy(self, request, *args, **kwargs):

class OverviewView(APIView):
def get(self, request):
stats = [{
today = timezone.now().date()
week_ago = today - timedelta(days=6)

# Get subjects count per day
subjects_per_day = (
Subject.objects
.filter(created_at__date__gte=week_ago)
.annotate(date=TruncDate('created_at'))
.values('date')
.annotate(subject_count=Count('id'))
.order_by('date')
)

# Get tests count per day
tests_per_day = (
Test.objects
.filter(created_at__date__gte=week_ago)
.annotate(date=TruncDate('created_at'))
.values('date')
.annotate(test_count=Count('id'))
.order_by('date')
)

# Create a list of all dates in the range
date_range = [(today - timedelta(days=x)) for x in range(6, -1, -1)]

# Convert querysets to dictionaries for easier lookup
subjects_dict = {item['date']: item['subject_count'] for item in subjects_per_day}
tests_dict = {item['date']: item['test_count'] for item in tests_per_day}

# Combine the results
weekly_stats = [
{
'date': date.strftime('%Y-%m-%d'),
'day': date.strftime('%A'),
'new_subjects': subjects_dict.get(date, 0),
'tests_taken': tests_dict.get(date, 0)
}
for date in date_range
]

data = {
'num_subjects': Subject.objects.filter(date_deleted__isnull=True).count(),
'num_tests': Test.objects.count(),
'num_diseases': Disease.objects.count(),
'num_users': User.objects.filter(date_deleted__isnull=True).count()
}]
'num_users': User.objects.filter(date_deleted__isnull=True).count(),
'weekly_stats': weekly_stats
}

return Response(stats)
return Response(data)

class TheaPagination(PageNumberPagination):
page_size = 10
Expand Down

0 comments on commit 4f4c5ee

Please sign in to comment.