Added Filter based querying for files

This commit is contained in:
2024-04-08 15:59:23 -04:00
parent 3a37faecd9
commit b3c4f7f2e8
2 changed files with 115 additions and 41 deletions

View File

@@ -55,5 +55,6 @@ urlpatterns = [
), ),
path("api/files/", views.FileListCreateAPIView.as_view(), name="file-list"), path("api/files/", views.FileListCreateAPIView.as_view(), name="file-list"),
path("api/files/<int:pk>/", views.FileDetailAPIView.as_view(), name="file-detail"), path("api/files/<int:pk>/", views.FileDetailAPIView.as_view(), name="file-detail"),
path("api/files/filter/", views.FileFilterView.as_view(), name="file-filter-view"),
path("api/register/", views.RegisterFile.as_view(), name="file-register"), path("api/register/", views.RegisterFile.as_view(), name="file-register"),
] ]

View File

@@ -1,4 +1,4 @@
from api.models import Course, File, Professor, Semester, Topic from api.models import Course, File, Professor, Semester, Topic, PeerUser
from api.serializers import ( from api.serializers import (
CourseSerializer, CourseSerializer,
FileSerializer, FileSerializer,
@@ -6,7 +6,9 @@ from api.serializers import (
SemesterSerializer, SemesterSerializer,
TopicSerializer, TopicSerializer,
) )
from datetime import datetime, timedelta
from django.contrib.auth import authenticate from django.contrib.auth import authenticate
from django.db import transaction
from rest_framework import generics, status from rest_framework import generics, status
from rest_framework.authentication import TokenAuthentication from rest_framework.authentication import TokenAuthentication
from rest_framework.authtoken.models import Token from rest_framework.authtoken.models import Token
@@ -112,6 +114,7 @@ class RegisterFile(APIView):
update_user_ip(request) update_user_ip(request)
data = request.data data = request.data
try: try:
with transaction.atomic():
required_fields = set( required_fields = set(
["filename", "topic", "semester", "professor", "course"] ["filename", "topic", "semester", "professor", "course"]
) )
@@ -123,7 +126,9 @@ class RegisterFile(APIView):
"Missing one or more of the required field(s): filename, topic" "Missing one or more of the required field(s): filename, topic"
) )
file = File.objects.create(filename=data["filename"], original_author=user) file = File.objects.create(
filename=data["filename"], original_author=user
)
file.peer_users.add(user) file.peer_users.add(user)
file.course = ( file.course = (
@@ -153,9 +158,17 @@ class RegisterFile(APIView):
topic = topic_serializer.save() topic = topic_serializer.save()
file.topic = topic file.topic = topic
response_data = {
"id": file.id,
"filename": file.filename,
"topic": file.topic.name if file.topic else None,
"semester": file.semester.name if file.semester else None,
"course": file.course.name if file.course else None,
"professor": file.professor.name if file.professor else None,
}
file.save() file.save()
return Response( return Response(
{"id": file.id, "filename": file.filename, "topic": file.topic.name}, response_data,
status=status.HTTP_201_CREATED, status=status.HTTP_201_CREATED,
) )
except Exception as e: except Exception as e:
@@ -163,3 +176,63 @@ class RegisterFile(APIView):
return Response( return Response(
{"error(s)": "Something went wrong"}, status=status.HTTP_400_BAD_REQUEST {"error(s)": "Something went wrong"}, status=status.HTTP_400_BAD_REQUEST
) )
class FileFilterView(APIView):
def get(self, request, format=None):
try:
# Extract filters from the query parameters
topic_id = request.query_params.get("topic")
professor_id = request.query_params.get("professor")
course_id = request.query_params.get("course")
semester_id = request.query_params.get("semester")
# Check if provided filter IDs exist
if topic_id and not Topic.objects.filter(id=topic_id).exists():
return Response(
{"error": f"Topic with id {topic_id} does not exist"},
status=status.HTTP_400_BAD_REQUEST,
)
if professor_id and not Professor.objects.filter(id=professor_id).exists():
return Response(
{"error": f"Professor with id {professor_id} does not exist"},
status=status.HTTP_400_BAD_REQUEST,
)
if course_id and not Course.objects.filter(id=course_id).exists():
return Response(
{"error": f"Course with id {course_id} does not exist"},
status=status.HTTP_400_BAD_REQUEST,
)
if semester_id and not Semester.objects.filter(id=semester_id).exists():
return Response(
{"error": f"Semester with id {semester_id} does not exist"},
status=status.HTTP_400_BAD_REQUEST,
)
# Start with the base queryset
queryset = File.objects.all()
# Apply filters if they are provided
if topic_id:
queryset = queryset.filter(topic__id=topic_id)
if professor_id:
queryset = queryset.filter(professor__id=professor_id)
if course_id:
queryset = queryset.filter(course__id=course_id)
if semester_id:
queryset = queryset.filter(semester__id=semester_id)
# Filter files based on active peers in the past hour
active_peer_ids = PeerUser.objects.filter(
last_poll__gte=datetime.now() - timedelta(hours=1)
).values_list("id", flat=True)
queryset = queryset.filter(peer_users__in=active_peer_ids).distinct()
serializer = FileSerializer(queryset, many=True)
return Response(serializer.data)
except Exception as e:
return Response(
{"error": f"Something went wrong: {str(e)}"},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)