From 6f971aa389defe37d91a0160fb473c9fc0d09686 Mon Sep 17 00:00:00 2001 From: mohsentaba Date: Sun, 7 Jun 2026 20:55:45 +0330 Subject: [PATCH] update certificate based on the new logic : all users can have certificates --- .../0003_alter_certificate_student.py | 21 +++++++++++++++ apps/certificate/models.py | 6 ++--- apps/certificate/views.py | 26 ++++++++++++------- 3 files changed, 39 insertions(+), 14 deletions(-) create mode 100644 apps/certificate/migrations/0003_alter_certificate_student.py diff --git a/apps/certificate/migrations/0003_alter_certificate_student.py b/apps/certificate/migrations/0003_alter_certificate_student.py new file mode 100644 index 0000000..7739cd5 --- /dev/null +++ b/apps/certificate/migrations/0003_alter_certificate_student.py @@ -0,0 +1,21 @@ +# Generated by Django 5.2.12 on 2026-06-07 16:49 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('certificate', '0002_alter_certificate_course_and_more'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AlterField( + model_name='certificate', + name='student', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='certificates', to=settings.AUTH_USER_MODEL, verbose_name='Student'), + ), + ] diff --git a/apps/certificate/models.py b/apps/certificate/models.py index b31eed2..f4a099d 100644 --- a/apps/certificate/models.py +++ b/apps/certificate/models.py @@ -4,7 +4,7 @@ from django.utils.translation import gettext_lazy as _ from filer.fields.file import FilerFileField from apps.course.models import Course from apps.course.models.course import extract_text_from_json -from apps.account.models import StudentUser +from apps.account.models import User @@ -15,7 +15,7 @@ class Certificate(models.Model): ('canceled', _('canceled')), ] - student = models.ForeignKey(StudentUser, on_delete=models.CASCADE, related_name='certificates', verbose_name=_('Student')) + student = models.ForeignKey(User, on_delete=models.CASCADE, related_name='certificates', verbose_name=_('Student')) course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='course_certificates', verbose_name=_('Course')) status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='pending', verbose_name=_('Status')) certificate_file = models.FileField(upload_to='certificates/', null=True, blank=True, verbose_name=_('certificate_file')) @@ -26,5 +26,3 @@ class Certificate(models.Model): def __str__(self): course_title = extract_text_from_json(self.course.title) if self.course_id else "" return f"Certificate {self.student.fullname} - {course_title}" - - diff --git a/apps/certificate/views.py b/apps/certificate/views.py index 14f2dac..dcba67e 100644 --- a/apps/certificate/views.py +++ b/apps/certificate/views.py @@ -1,11 +1,13 @@ from rest_framework import generics, permissions +from rest_framework.viewsets import ModelViewSet from rest_framework.authentication import TokenAuthentication from drf_yasg.utils import swagger_auto_schema from drf_yasg import openapi from django.db.models import Q from apps.certificate.models import Certificate -from apps.certificate.serializers import CertificateRequestSerializer, CertificateSerializer +from apps.certificate.serializers import AdminCertificateSerializer, CertificateRequestSerializer, CertificateSerializer +from apps.account.permissions import IsSuperAdmin from apps.course.models import Course from apps.course.models.course import extract_text_from_json from utils.pagination import StandardResultsSetPagination @@ -57,7 +59,6 @@ class CertificateRequestView(generics.CreateAPIView): serializer.save(student=self.request.user) - class UserCertificatesListView(generics.ListAPIView): serializer_class = CertificateSerializer permission_classes = [permissions.IsAuthenticated] @@ -81,12 +82,6 @@ class UserCertificatesListView(generics.ListAPIView): return Certificate.objects.filter(student=self.request.user).order_by('-created_at') -from rest_framework.viewsets import ModelViewSet -from apps.certificate.serializers import AdminCertificateSerializer -from apps.account.permissions import IsPanelUser, IsSuperAdmin -from django.db.models import Q - - def is_professor(request): return getattr(request.user, 'user_type', None) == 'professor' @@ -107,12 +102,23 @@ class AdminCertificateViewSet(ModelViewSet): # Search query search_query = self.request.query_params.get('search', None) + has_search = False if search_query: + has_search = True matching_course_ids = find_matching_course_ids(search_query) + from django.db.models import Case, When, Value, IntegerField queryset = queryset.filter( Q(student__fullname__icontains=search_query) | Q(student__email__icontains=search_query) | Q(course_id__in=matching_course_ids) + ).annotate( + search_relevance=Case( + When(student__fullname__icontains=search_query, then=Value(3)), + When(student__email__icontains=search_query, then=Value(2)), + When(course_id__in=matching_course_ids, then=Value(1)), + default=Value(0), + output_field=IntegerField() + ) ) # Filters @@ -140,6 +146,6 @@ class AdminCertificateViewSet(ModelViewSet): if issued_before: queryset = queryset.filter(created_at__date__lte=issued_before) + if has_search: + return queryset.order_by('-search_relevance', '-created_at') return queryset.order_by('-created_at') - -