Added endpoint for querying avatars of users in a study group and for individual study group details

This commit is contained in:
Keannu Bernasol 2023-10-01 01:24:58 +08:00
parent 0ecfb2223a
commit c8fca412b8
7 changed files with 199 additions and 16 deletions

View file

@ -0,0 +1,21 @@
# Generated by Django 4.2.3 on 2023-09-30 15:35
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('accounts', '0002_initial'),
]
operations = [
migrations.AlterModelOptions(
name='customuser',
options={},
),
migrations.AlterUniqueTogether(
name='customuser',
unique_together={('first_name', 'last_name')},
),
]

View file

@ -135,7 +135,7 @@ paths:
name: id
schema:
type: integer
description: A unique integer value identifying this user.
description: A unique integer value identifying this custom user.
required: true
tags:
- api
@ -155,7 +155,7 @@ paths:
name: id
schema:
type: integer
description: A unique integer value identifying this user.
description: A unique integer value identifying this custom user.
required: true
tags:
- api
@ -187,7 +187,7 @@ paths:
name: id
schema:
type: integer
description: A unique integer value identifying this user.
description: A unique integer value identifying this custom user.
required: true
tags:
- api
@ -218,7 +218,7 @@ paths:
name: id
schema:
type: integer
description: A unique integer value identifying this user.
description: A unique integer value identifying this custom user.
required: true
tags:
- api
@ -763,6 +763,26 @@ paths:
items:
$ref: '#/components/schemas/StudyGroup'
description: ''
/api/v1/study_groups/{name}/:
get:
operationId: api_v1_study_groups_retrieve
parameters:
- in: path
name: name
schema:
type: string
required: true
tags:
- api
security:
- jwtAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/StudyGroupDetail'
description: ''
/api/v1/study_groups/create/:
post:
operationId: api_v1_study_groups_create_create
@ -851,7 +871,7 @@ paths:
schema:
type: array
items:
$ref: '#/components/schemas/StudyGroup'
$ref: '#/components/schemas/StudyGroupDistance'
description: ''
/api/v1/subjects/:
get:
@ -1068,21 +1088,18 @@ components:
readOnly: true
user:
type: string
description: Required. 150 characters or fewer. Letters, digits and @/./+/-/_
only.
study_group:
type: string
message_content:
type: string
maxLength: 1024
timestamp:
type: string
format: date-time
readOnly: true
required:
- id
- message_content
- study_group
- timestamp
- user
PasswordResetConfirm:
type: object
properties:
@ -1348,6 +1365,75 @@ components:
- name
- subject
- timestamp
StudyGroupDetail:
type: object
properties:
id:
type: integer
readOnly: true
name:
type: string
students:
type: array
items:
type: string
subject:
type: string
location:
type: string
landmark:
type: string
nullable: true
timestamp:
type: string
format: date
readOnly: true
required:
- id
- location
- name
- students
- subject
- timestamp
StudyGroupDistance:
type: object
properties:
id:
type: integer
readOnly: true
name:
type: string
students:
type: array
items:
type: string
subject:
type: string
location:
type: string
landmark:
type: string
nullable: true
radius:
type: number
format: double
distance:
type: string
readOnly: true
default: 0
timestamp:
type: string
format: date
readOnly: true
required:
- distance
- id
- location
- name
- radius
- students
- subject
- timestamp
SubjectInstance:
type: object
properties:

View file

@ -4,6 +4,16 @@ from accounts.models import CustomUser
from subjects.models import Subject
from drf_extra_fields.geo_fields import PointField
from landmarks.models import Landmark
from drf_extra_fields.fields import Base64ImageField
from djoser.serializers import UserSerializer as BaseUserSerializer
class CustomUserAvatarSerializer(BaseUserSerializer):
avatar = Base64ImageField()
class Meta(BaseUserSerializer.Meta):
model = CustomUser
fields = ['avatar', 'username']
class CustomUserKeyRelatedField(serializers.PrimaryKeyRelatedField):
@ -13,6 +23,21 @@ class CustomUserKeyRelatedField(serializers.PrimaryKeyRelatedField):
return str(value)
class StudyGroupDetailSerializer(serializers.ModelSerializer):
name = serializers.CharField()
students = serializers.StringRelatedField(many=True)
subject = serializers.SlugRelatedField(
many=False, slug_field='name', queryset=Subject.objects.all(), required=True, allow_null=False)
location = PointField()
landmark = serializers.SlugRelatedField(
queryset=Landmark.objects.all(), many=False, slug_field='name', required=False, allow_null=True)
class Meta:
model = StudyGroup
fields = '__all__'
read_only_fields = ['landmark', 'radius', 'students', 'distance']
class StudyGroupSerializer(serializers.ModelSerializer):
name = serializers.CharField()
students = serializers.StringRelatedField(many=True)

View file

@ -1,5 +1,5 @@
from django.urls import include, path
from .views import StudyGroupListView, StudyGroupListNearView, StudyGroupCreateView
from .views import StudyGroupListView, StudyGroupListNearView, StudyGroupCreateView, StudyGroupDetailView, StudyGroupAvatarsView
from rest_framework import routers
router = routers.DefaultRouter()
@ -7,7 +7,10 @@ router.register(r'create', StudyGroupCreateView,
basename='Create Study Group')
urlpatterns = [
path('', StudyGroupListView.as_view()),
path('near/', StudyGroupListNearView.as_view()),
path('', include(router.urls)),
path('near/', StudyGroupListNearView.as_view()),
path('member_avatars/', StudyGroupAvatarsView.as_view()),
path('<str:name>/', StudyGroupDetailView.as_view()),
]

View file

@ -2,7 +2,7 @@ from django.shortcuts import render
from rest_framework import generics, mixins
from rest_framework.exceptions import PermissionDenied
from rest_framework.permissions import IsAuthenticated
from .serializers import StudyGroupSerializer, StudyGroupCreateSerializer, StudyGroupDistanceSerializer
from .serializers import StudyGroupSerializer, StudyGroupCreateSerializer, StudyGroupDistanceSerializer, StudyGroupDetailSerializer, CustomUserAvatarSerializer
from .models import StudyGroup
from subjects.models import Subject, SubjectInstance
from student_status.models import StudentStatus
@ -12,10 +12,48 @@ from django.contrib.gis.db.models.functions import Distance
from rest_framework import status
from rest_framework.response import Response
from rest_framework import permissions
from accounts.models import CustomUser
# Create your views here.
class StudyGroupAvatarsView(generics.ListAPIView):
permission_classes = [IsAuthenticated]
serializer_class = CustomUserAvatarSerializer
queryset = CustomUser.objects.all()
def get_queryset(self):
# Get user
user = self.request.user
# Get status of user
user_status = StudentStatus.objects.filter(user=user).first()
# Return error if not in study group
if (not user_status.study_group):
raise exceptions.ValidationError("You are not in a study group")
# Get study group of user
user_study_group = user_status.study_group
# Get students in that study group
study_group_student_ids = user_study_group.students.values_list(
'user', flat=True)
# Then get user instances of those students
study_group_users = CustomUser.objects.filter(
id__in=study_group_student_ids)
# Return to be parsed by serializer
return study_group_users
class StudyGroupMembersAvatarView(generics.ListAPIView):
permission_classes = [IsAuthenticated]
serializer_class = StudyGroupCreateSerializer
queryset = CustomUser.objects.all()
class StudyGroupCreateView(viewsets.ModelViewSet):
http_method_names = ['patch', 'post', 'delete']
permission_classes = [IsAuthenticated]
@ -23,6 +61,13 @@ class StudyGroupCreateView(viewsets.ModelViewSet):
queryset = StudyGroup.objects.all()
class StudyGroupDetailView(generics.RetrieveAPIView):
permission_classes = [IsAuthenticated]
serializer_class = StudyGroupDetailSerializer
queryset = StudyGroup.objects.all()
lookup_field = 'name'
class StudyGroupListView(generics.ListAPIView):
permission_classes = [IsAuthenticated]
serializer_class = StudyGroupSerializer

View file

@ -6,10 +6,13 @@ from study_groups.models import StudyGroup
class MessageSerializer(serializers.ModelSerializer):
user = serializers.SlugRelatedField(
queryset=CustomUser.objects.all(), slug_field='full_name', required=True)
queryset=CustomUser.objects.all(), slug_field='username', required=False)
study_group = serializers.SlugRelatedField(
queryset=StudyGroup.objects.all(), slug_field='name', required=True)
queryset=StudyGroup.objects.all(), slug_field='name', required=False)
message_content = serializers.CharField()
timestamp = serializers.DateTimeField(format="%I:%M %p", required=False)
class Meta:
model = Message
fields = '__all__'
read_only_fields = ['user', 'study_group', 'timestamp']

View file

@ -48,5 +48,5 @@ class MessageViewSet(viewsets.ModelViewSet):
# Now fetch the Messages matching the study group id
messages = Message.objects.filter(
study_group=user_study_group).order_by('-timestamp')
study_group=user_study_group).order_by('timestamp')
return messages