Browse Source

swagger problem resolved with adding ref_name to views

master
Mohsen Taba 2 months ago
parent
commit
011b25d017
  1. 70
      apps/account/permissions.py
  2. 42
      apps/account/views/user.py
  3. 9
      apps/blog/views_admin.py
  4. 13
      apps/certificate/views.py
  5. 3
      apps/course/serializers/admin.py
  6. 127
      apps/course/views/admin.py
  7. 1
      apps/quiz/serializers/admin.py
  8. 47
      apps/quiz/views/admin.py
  9. 14
      apps/transaction/views.py

70
apps/account/permissions.py

@ -1,12 +1,58 @@
from rest_framework.permissions import BasePermission
class IsActiveUser(BasePermission):
def has_permission(self, request, view):
return request.user and request.user.is_active
from rest_framework.permissions import BasePermission, SAFE_METHODS
class IsActiveUser(BasePermission):
def has_permission(self, request, view):
return request.user and request.user.is_active
class IsSuperAdmin(BasePermission):
"""
Allows access only to super admins and staff admins.
"""
def has_permission(self, request, view):
return (
request.user and
request.user.is_authenticated and
request.user.is_active and
(request.user.is_superuser or request.user.user_type in ['super_admin', 'admin'])
)
class IsPanelUser(BasePermission):
"""
Allows access to all administrative panel roles: super admins, admins, and professors.
"""
def has_permission(self, request, view):
return (
request.user and
request.user.is_authenticated and
request.user.is_active and
(request.user.is_superuser or request.user.user_type in ['super_admin', 'admin', 'professor'])
)
class IsSuperAdminOrReadOnlyForProfessor(BasePermission):
"""
Allows full read-write access to super admins/admins,
but only read-only (GET, HEAD, OPTIONS) access to professors.
"""
def has_permission(self, request, view):
if not request.user or not request.user.is_authenticated or not request.user.is_active:
return False
# Super admin / Admin can do everything
if request.user.is_superuser or request.user.user_type in ['super_admin', 'admin']:
return True
# Professor has read-only access
if request.user.user_type == 'professor':
return request.method in SAFE_METHODS
return False

42
apps/account/views/user.py

@ -29,7 +29,7 @@ from utils.redis import RedisManager
from utils.exceptions import AppAPIException
from utils import send_email, is_valid_email
from config.settings import base as settings
from apps.account.permissions import IsActiveUser
from apps.account.permissions import IsActiveUser, IsSuperAdminOrReadOnlyForProfessor
from apps.account.doc import *
logger = logging.getLogger(__name__)
@ -424,7 +424,7 @@ class UserLoginView(CreateAPIView):
"fullname": user.fullname,
"email": user.email,
"token": token.key,
"user_type": user.user_type_based_on_groups,
"user_type": user.user_type,
"avatar": request.build_absolute_uri(user.avatar.url) if user.avatar else None,
}, status=status.HTTP_201_CREATED)
@ -583,18 +583,27 @@ class AdminLoginView(CreateAPIView):
serializer.is_valid(raise_exception=True)
data = serializer.data
email = request.data['email']
email = request.data['email'].strip().lower()
try:
user_obj = User.objects.get(email=email)
user_obj = User.objects.get(email__iexact=email)
except User.DoesNotExist:
raise ValidationError({"email": "No admin found with that information."})
# --- THE CRUCIAL ADMIN CHECK ---
# Adjust 'is_staff' or 'is_superuser' based on how you define admins in Django
if not (user_obj.is_staff or user_obj.is_superuser):
# --- PANEL ACCESS CHECK ---
# Allow super_admin, admin (is_staff/is_superuser), professors
# Check both user_type field AND group membership (in case they differ)
ALLOWED_TYPES = ('professor', 'admin', 'super_admin')
is_panel_user = (
user_obj.is_staff or
user_obj.is_superuser or
getattr(user_obj, 'user_type', None) in ALLOWED_TYPES or
user_obj.groups.filter(name="Professor Group").exists()
)
if not is_panel_user:
raise AuthenticationFailed("No admin found with that information.")
user = authenticate(request, username=email, password=data['password'])
# Use the actual stored email for authentication (ensures case matches DB)
user = authenticate(request, username=user_obj.email, password=data['password'])
if not user:
raise ValidationError({"password": "Password is incorrect"})
@ -612,12 +621,18 @@ class AdminLoginView(CreateAPIView):
device_os='web_admin'
)
# Determine effective user_type (user_type field may lag behind groups)
effective_user_type = user.user_type
if effective_user_type not in ('professor', 'admin', 'super_admin'):
if user.groups.filter(name="Professor Group").exists():
effective_user_type = 'professor'
return Response({
"id": user.id,
"fullname": user.fullname,
"email": user.email,
"token": token.key,
"user_type": user.user_type_based_on_groups,
"user_type": effective_user_type,
"avatar": request.build_absolute_uri(user.avatar.url) if user.avatar else None,
}, status=status.HTTP_201_CREATED)
@ -634,7 +649,7 @@ class AdminUserViewSet(ModelViewSet):
Includes searching, filtering, and pagination.
"""
serializer_class = AdminUserSerializer
permission_classes = [IsAuthenticated, IsAdminUser] # Strictly admin only
permission_classes = [IsAuthenticated, IsSuperAdminOrReadOnlyForProfessor]
authentication_classes = [TokenAuthentication]
pagination_class = StandardResultsSetPagination
filter_backends = [] # Disable default backend filtering to use custom manual filtering
@ -642,6 +657,13 @@ class AdminUserViewSet(ModelViewSet):
def get_queryset(self):
queryset = User.objects.filter(is_active=True, email__isnull=False).exclude(email='')
# Restrict queryset for professors to only students of their courses
if self.request.user.user_type == 'professor':
queryset = queryset.filter(
user_type='student',
participated_courses__course__professor_id=self.request.user.id
)
# Handle Search
search_query = self.request.query_params.get('search', None)
if search_query:

9
apps/blog/views_admin.py

@ -1,6 +1,7 @@
from django.db.models import Q
from rest_framework.viewsets import ModelViewSet
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework.permissions import IsAuthenticated
from apps.account.permissions import IsSuperAdmin
from rest_framework.authentication import TokenAuthentication
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser
from rest_framework.decorators import action
@ -19,7 +20,7 @@ class AdminBlogViewSet(ModelViewSet):
"""
Admin CRUD ViewSet for Blog management.
"""
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsSuperAdmin]
authentication_classes = [TokenAuthentication]
pagination_class = StandardResultsSetPagination
# Allow multipart so admins can upload thumbnail images directly
@ -63,7 +64,7 @@ class AdminBlogContentViewSet(ModelViewSet):
Admin CRUD ViewSet for managing the content blocks inside a specific blog.
"""
serializer_class = AdminBlogContentSerializer
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsSuperAdmin]
authentication_classes = [TokenAuthentication]
parser_classes = (MultiPartParser, FormParser, JSONParser)
@ -103,7 +104,7 @@ class AdminBlogSeoViewSet(ModelViewSet):
Admin CRUD ViewSet for managing SEO meta tags for a specific blog.
"""
serializer_class = AdminBlogSeoSerializer
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsSuperAdmin]
authentication_classes = [TokenAuthentication]
def get_queryset(self):

13
apps/certificate/views.py

@ -56,19 +56,28 @@ class UserCertificatesListView(generics.ListAPIView):
from rest_framework.viewsets import ModelViewSet
from rest_framework.permissions import IsAdminUser
from apps.certificate.serializers import AdminCertificateSerializer
from apps.account.permissions import IsPanelUser
from django.db.models import Q
def is_professor(request):
return getattr(request.user, 'user_type', None) == 'professor'
class AdminCertificateViewSet(ModelViewSet):
queryset = Certificate.objects.all()
serializer_class = AdminCertificateSerializer
permission_classes = [permissions.IsAuthenticated, IsAdminUser]
permission_classes = [permissions.IsAuthenticated, IsPanelUser]
authentication_classes = [TokenAuthentication]
pagination_class = StandardResultsSetPagination
def get_queryset(self):
queryset = Certificate.objects.all().select_related('student', 'course')
# Professors can only see certificates for students in their courses
if is_professor(self.request):
queryset = queryset.filter(course__professor_id=self.request.user.id)
# Search query
search_query = self.request.query_params.get('search', None)

3
apps/course/serializers/admin.py

@ -152,6 +152,9 @@ class AdminCourseLessonSerializer(serializers.Serializer):
video_link = serializers.CharField(max_length=500, required=False, allow_blank=True, allow_null=True)
duration = serializers.IntegerField(min_value=0, required=False, default=0)
class Meta:
ref_name = 'CourseAdminCourseLesson'
def to_representation(self, instance):
"""
Map a CourseLesson instance to representation fields.

127
apps/course/views/admin.py

@ -1,10 +1,12 @@
from django.db.models import Q
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import TokenAuthentication
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.exceptions import PermissionDenied
from utils.pagination import StandardResultsSetPagination
from apps.account.permissions import IsPanelUser, IsSuperAdminOrReadOnlyForProfessor
from apps.course.models import (
Course,
CourseCategory,
@ -34,11 +36,17 @@ from apps.course.serializers.admin import (
AdminLiveSessionDetailSerializer
)
def is_professor(request):
return getattr(request.user, 'user_type', None) == 'professor'
class AdminCourseViewSet(viewsets.ModelViewSet):
"""
Admin CRUD ViewSet for Course management.
Professors can only access/modify their own courses.
"""
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsPanelUser]
authentication_classes = [TokenAuthentication]
pagination_class = StandardResultsSetPagination
@ -50,6 +58,10 @@ class AdminCourseViewSet(viewsets.ModelViewSet):
def get_queryset(self):
queryset = Course.objects.all().select_related('category', 'professor')
# Professors can only see their own courses
if is_professor(self.request):
queryset = queryset.filter(professor_id=self.request.user.id)
# Search Query
search_query = self.request.query_params.get('search', None)
if search_query:
@ -81,18 +93,41 @@ class AdminCourseViewSet(viewsets.ModelViewSet):
return queryset.order_by('-id')
def perform_create(self, serializer):
# If the logged-in user is a professor, force the professor field to themselves
if is_professor(self.request):
serializer.save(professor_id=self.request.user.id)
else:
serializer.save()
def perform_update(self, serializer):
# Prevent professors from reassigning a course to another professor
if is_professor(self.request):
instance = self.get_object()
if instance.professor_id != self.request.user.id:
raise PermissionDenied("You can only edit your own courses.")
serializer.save(professor_id=self.request.user.id)
else:
serializer.save()
class AdminChapterViewSet(viewsets.ModelViewSet):
"""
Admin CRUD ViewSet for Course Chapters.
Professors can only access chapters of their own courses.
"""
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsPanelUser]
authentication_classes = [TokenAuthentication]
serializer_class = AdminCourseChapterSerializer
pagination_class = None
def get_queryset(self):
queryset = CourseChapter.objects.all()
# Professors can only see chapters of their own courses
if is_professor(self.request):
queryset = queryset.filter(course__professor_id=self.request.user.id)
course_id = self.request.query_params.get('course', None)
if course_id:
queryset = queryset.filter(course_id=course_id)
@ -119,15 +154,20 @@ class AdminChapterViewSet(viewsets.ModelViewSet):
class AdminCourseLessonViewSet(viewsets.ModelViewSet):
"""
Admin CRUD ViewSet for Lessons associated with a Course/Chapter.
Professors can only access lessons in their own courses.
"""
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsPanelUser]
authentication_classes = [TokenAuthentication]
serializer_class = AdminCourseLessonSerializer
pagination_class = None
def get_queryset(self):
queryset = CourseLesson.objects.all().select_related('lesson', 'chapter')
# Professors can only see lessons of their own courses
if is_professor(self.request):
queryset = queryset.filter(course__professor_id=self.request.user.id)
course_id = self.request.query_params.get('course', None)
if course_id:
queryset = queryset.filter(course_id=course_id)
@ -166,14 +206,20 @@ class AdminCourseLessonViewSet(viewsets.ModelViewSet):
class AdminCourseAttachmentViewSet(viewsets.ModelViewSet):
"""
Admin CRUD ViewSet for Course Attachments.
Professors can only access attachments of their own courses.
"""
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsPanelUser]
authentication_classes = [TokenAuthentication]
serializer_class = AdminCourseAttachmentSerializer
pagination_class = None
def get_queryset(self):
queryset = CourseAttachment.objects.all().select_related('attachment')
# Professors can only see attachments of their own courses
if is_professor(self.request):
queryset = queryset.filter(course__professor_id=self.request.user.id)
course_id = self.request.query_params.get('course', None)
if course_id:
queryset = queryset.filter(course_id=course_id)
@ -190,14 +236,20 @@ class AdminCourseAttachmentViewSet(viewsets.ModelViewSet):
class AdminCourseGlossaryViewSet(viewsets.ModelViewSet):
"""
Admin CRUD ViewSet for Course Glossary terms.
Professors can only access glossaries of their own courses.
"""
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsPanelUser]
authentication_classes = [TokenAuthentication]
serializer_class = AdminCourseGlossarySerializer
pagination_class = None
def get_queryset(self):
queryset = CourseGlossary.objects.all().select_related('glossary')
# Professors can only see glossaries of their own courses
if is_professor(self.request):
queryset = queryset.filter(course__professor_id=self.request.user.id)
course_id = self.request.query_params.get('course', None)
if course_id:
queryset = queryset.filter(course_id=course_id)
@ -214,12 +266,13 @@ class AdminCourseGlossaryViewSet(viewsets.ModelViewSet):
class AdminCourseCategoryViewSet(viewsets.ModelViewSet):
"""
Admin CRUD ViewSet for Course Categories.
Professors have read-only access.
"""
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsSuperAdminOrReadOnlyForProfessor]
authentication_classes = [TokenAuthentication]
serializer_class = AdminCourseCategorySerializer
pagination_class = StandardResultsSetPagination
def get_queryset(self):
queryset = CourseCategory.objects.all().order_by('-id')
search = self.request.query_params.get('search', None)
@ -230,37 +283,53 @@ class AdminCourseCategoryViewSet(viewsets.ModelViewSet):
class AdminLessonViewSet(viewsets.ModelViewSet):
"""
Admin CRUD ViewSet for base Lesson.
Admin CRUD ViewSet for base Lesson (Repository).
Professors can only see lessons linked to their own courses.
"""
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsPanelUser]
authentication_classes = [TokenAuthentication]
serializer_class = AdminLessonSerializer
pagination_class = StandardResultsSetPagination
def get_queryset(self):
queryset = Lesson.objects.all().order_by('-id')
# Professors can only see lessons associated with their own courses
if is_professor(self.request):
queryset = queryset.filter(
course_lessons__course__professor_id=self.request.user.id
).distinct()
search = self.request.query_params.get('search', None)
if search:
queryset = queryset.filter(title__icontains=search)
content_type = self.request.query_params.get('content_type', None)
if content_type:
queryset = queryset.filter(content_type=content_type)
return queryset
class AdminGlossaryViewSet(viewsets.ModelViewSet):
"""
Admin CRUD ViewSet for base Glossary.
Admin CRUD ViewSet for base Glossary (Repository).
Professors can only see glossaries linked to their own courses.
"""
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsPanelUser]
authentication_classes = [TokenAuthentication]
serializer_class = AdminGlossarySerializer
pagination_class = StandardResultsSetPagination
def get_queryset(self):
queryset = Glossary.objects.all().order_by('-id')
# Professors can only see glossaries associated with their own courses
if is_professor(self.request):
queryset = queryset.filter(
course_glossaries__course__professor_id=self.request.user.id
).distinct()
search = self.request.query_params.get('search', None)
if search:
queryset = queryset.filter(Q(title__icontains=search) | Q(description__icontains=search))
@ -269,15 +338,23 @@ class AdminGlossaryViewSet(viewsets.ModelViewSet):
class AdminAttachmentViewSet(viewsets.ModelViewSet):
"""
Admin CRUD ViewSet for base Attachment.
Admin CRUD ViewSet for base Attachment (Repository).
Professors can only see attachments linked to their own courses.
"""
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsPanelUser]
authentication_classes = [TokenAuthentication]
serializer_class = AdminAttachmentSerializer
pagination_class = StandardResultsSetPagination
def get_queryset(self):
queryset = Attachment.objects.all().order_by('-id')
# Professors can only see attachments associated with their own courses
if is_professor(self.request):
queryset = queryset.filter(
course_attachments__course__professor_id=self.request.user.id
).distinct()
search = self.request.query_params.get('search', None)
if search:
queryset = queryset.filter(title__icontains=search)
@ -287,8 +364,9 @@ class AdminAttachmentViewSet(viewsets.ModelViewSet):
class AdminLiveSessionViewSet(viewsets.ModelViewSet):
"""
Admin CRUD ViewSet for Course Live Sessions.
Professors can only access live sessions of their own courses.
"""
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsPanelUser]
authentication_classes = [TokenAuthentication]
pagination_class = StandardResultsSetPagination
@ -299,7 +377,11 @@ class AdminLiveSessionViewSet(viewsets.ModelViewSet):
def get_queryset(self):
queryset = CourseLiveSession.objects.all().select_related('course')
# Professors can only see live sessions of their own courses
if is_professor(self.request):
queryset = queryset.filter(course__professor_id=self.request.user.id)
search = self.request.query_params.get('search', None)
if search:
queryset = queryset.filter(
@ -329,4 +411,3 @@ class AdminLiveSessionViewSet(viewsets.ModelViewSet):
queryset = queryset.filter(ended_at__lte=ended_before)
return queryset.order_by('-started_at')

1
apps/quiz/serializers/admin.py

@ -16,6 +16,7 @@ class AdminCourseLessonSerializer(serializers.ModelSerializer):
class Meta:
model = CourseLesson
fields = ['id', 'title']
ref_name = 'QuizAdminCourseLesson'
def get_title(self, obj):
if obj.title:

47
apps/quiz/views/admin.py

@ -1,7 +1,7 @@
from django.db.models import Q
from rest_framework.viewsets import ModelViewSet
from rest_framework.generics import ListAPIView
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import TokenAuthentication
from rest_framework.decorators import action
from rest_framework.response import Response
@ -11,6 +11,7 @@ from utils.pagination import StandardResultsSetPagination
from apps.quiz.models import Quiz, Question, QuizParticipant
from apps.course.models import Course, CourseLesson, Participant
from apps.account.models import User
from apps.account.permissions import IsPanelUser
from apps.quiz.serializers.admin import (
AdminCourseSerializer,
@ -23,12 +24,16 @@ from apps.quiz.serializers.admin import (
)
def is_professor(request):
return getattr(request.user, 'user_type', None) == 'professor'
class AdminQuizViewSet(ModelViewSet):
"""
Admin CRUD ViewSet for Quiz management.
Includes searching, filtering, and retrieving participants/absentees list.
Professors can only access quizzes of their own courses.
"""
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsPanelUser]
authentication_classes = [TokenAuthentication]
pagination_class = StandardResultsSetPagination
@ -40,6 +45,10 @@ class AdminQuizViewSet(ModelViewSet):
def get_queryset(self):
queryset = Quiz.objects.all().select_related('course', 'lesson')
# Professors can only see quizzes of their own courses
if is_professor(self.request):
queryset = queryset.filter(course__professor_id=self.request.user.id)
# Handle Search
search_query = self.request.query_params.get('search', None)
if search_query:
@ -110,16 +119,20 @@ class AdminQuizViewSet(ModelViewSet):
class AdminQuestionViewSet(ModelViewSet):
"""
Admin CRUD ViewSet for Question management.
Usually filtered by quiz_id.
Professors can only access questions of quizzes belonging to their own courses.
"""
serializer_class = AdminQuestionSerializer
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsPanelUser]
authentication_classes = [TokenAuthentication]
pagination_class = None
def get_queryset(self):
queryset = Question.objects.all()
# Professors can only see questions of their own courses' quizzes
if is_professor(self.request):
queryset = queryset.filter(quiz__course__professor_id=self.request.user.id)
quiz_id = self.request.query_params.get('quiz_id', None)
if not quiz_id:
# Fallback parameter name
@ -162,25 +175,39 @@ class AdminQuestionViewSet(ModelViewSet):
class AdminCourseListView(ListAPIView):
"""
Dropdown listing helper for all courses.
Professors only see their own courses.
"""
queryset = Course.objects.all().order_by('-id')
serializer_class = AdminCourseSerializer
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsPanelUser]
authentication_classes = [TokenAuthentication]
pagination_class = None # Return all courses for dropdown usage
def get_queryset(self):
queryset = Course.objects.all().order_by('-id')
if is_professor(self.request):
queryset = queryset.filter(professor_id=self.request.user.id)
return queryset
class AdminLessonListView(ListAPIView):
"""
Dropdown listing helper for lessons. Filtered by course_id.
Professors only see lessons of their own courses.
"""
serializer_class = AdminCourseLessonSerializer
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsPanelUser]
authentication_classes = [TokenAuthentication]
pagination_class = None # Return all matching lessons for dropdown usage
def get_queryset(self):
course_id = self.request.query_params.get('course_id', None)
if course_id:
return CourseLesson.objects.filter(course_id=course_id).select_related('lesson').order_by('priority')
return CourseLesson.objects.all().select_related('lesson').order_by('-id')
qs = CourseLesson.objects.filter(course_id=course_id).select_related('lesson').order_by('priority')
else:
qs = CourseLesson.objects.all().select_related('lesson').order_by('-id')
# Professors only see lessons of their own courses
if is_professor(self.request):
qs = qs.filter(course__professor_id=self.request.user.id)
return qs

14
apps/transaction/views.py

@ -417,19 +417,25 @@ class TransactionReceiptsListView(generics.ListAPIView):
# =============================================================================
from rest_framework.viewsets import ModelViewSet
from rest_framework.permissions import IsAdminUser
from apps.transaction.serializers import AdminTransactionSerializer
from apps.account.permissions import IsPanelUser
from django.db.models import Q
from utils.pagination import StandardResultsSetPagination
def is_professor(request):
return getattr(request.user, 'user_type', None) == 'professor'
class AdminTransactionViewSet(ModelViewSet):
"""
Admin-only viewset for viewing and updating transactions.
Only GET (list/retrieve) and PATCH (update status) are allowed.
Professors only see transactions for their own courses.
"""
queryset = TransactionParticipant.objects.all()
serializer_class = AdminTransactionSerializer
permission_classes = [IsAuthenticated, IsAdminUser]
permission_classes = [IsAuthenticated, IsPanelUser]
authentication_classes = [TokenAuthentication]
pagination_class = StandardResultsSetPagination
http_method_names = ['get', 'patch', 'head', 'options']
@ -437,6 +443,10 @@ class AdminTransactionViewSet(ModelViewSet):
def get_queryset(self):
queryset = TransactionParticipant.objects.all().select_related('user', 'course').prefetch_related('receipts', 'participant_infos')
# Professors can only see transactions for their own courses
if is_professor(self.request):
queryset = queryset.filter(course__professor_id=self.request.user.id)
# Search
search_query = self.request.query_params.get('search', None)
if search_query:

Loading…
Cancel
Save