diff --git a/Questions/migrations/0002_questionassignment.py b/Questions/migrations/0002_questionassignment.py new file mode 100644 index 0000000..737ab4c --- /dev/null +++ b/Questions/migrations/0002_questionassignment.py @@ -0,0 +1,46 @@ +# Generated by Django 4.2.4 on 2026-01-02 18:33 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ("clients", "0008_alter_mentor_supermentor"), + ("Questions", "0001_initial"), + ] + + operations = [ + migrations.CreateModel( + name="QuestionAssignment", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("assigned_at", models.DateTimeField(auto_now_add=True)), + ( + "mentee", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="clients.mentee" + ), + ), + ( + "question", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="Questions.question", + ), + ), + ], + options={ + "unique_together": {("question", "mentee")}, + }, + ), + ] diff --git a/Questions/migrations/0003_question_scope_alter_question_level.py b/Questions/migrations/0003_question_scope_alter_question_level.py new file mode 100644 index 0000000..7f4dcc6 --- /dev/null +++ b/Questions/migrations/0003_question_scope_alter_question_level.py @@ -0,0 +1,29 @@ +# Generated by Django 4.2.4 on 2026-01-08 07:39 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("Questions", "0002_questionassignment"), + ] + + operations = [ + migrations.AddField( + model_name="question", + name="scope", + field=models.CharField( + choices=[("TEAM", "Team"), ("ALL", "All")], + default="TEAM", + max_length=10, + ), + ), + migrations.AlterField( + model_name="question", + name="Level", + field=models.CharField( + choices=[("1", "Easy"), ("2", "Medium"), ("3", "Hard")], max_length=200 + ), + ), + ] diff --git a/Questions/models.py b/Questions/models.py index a87bc63..68b2f85 100644 --- a/Questions/models.py +++ b/Questions/models.py @@ -1,45 +1,58 @@ from django.db import models from clients.models import Mentee -from django.utils.timezone import utc from django.utils import timezone import datetime from django.core.validators import MaxValueValidator, MinValueValidator -difficulty={ - ("1","Easy"), - ("2","Medium"), - ("3","Hard") -} +# Fix your choices format (tuples instead of sets) +DIFFICULTY_CHOICES = [ + ("1", "Easy"), + ("2", "Medium"), + ("3", "Hard") +] -DSA_topic={ - ("1","Array"), - ("2","Matrix"), - ("3","String"), - ("4","Search & Sort"), - ("5","Linked List"), - ("6","Binary Trees"), - ("7","BST"), - ("8","Greedy"), - ("9","Backtracking"), - ("10","Stacks & Queues"), - ("11","Heaps"), - ("12","Graphs"), - ("13","Tries"), - ("14","Dynamic Programming"), - ("15","Bit Manipulation") -} +DSA_TOPIC_CHOICES = [ + ("1", "Array"), + ("2", "Matrix"), + ("3", "String"), + ("4", "Search & Sort"), + ("5", "Linked List"), + ("6", "Binary Trees"), + ("7", "BST"), + ("8", "Greedy"), + ("9", "Backtracking"), + ("10", "Stacks & Queues"), + ("11", "Heaps"), + ("12", "Graphs"), + ("13", "Tries"), + ("14", "Dynamic Programming"), + ("15", "Bit Manipulation") +] + +SCOPE_CHOICES = [ + ("TEAM", "Team"), # Default - only mentor's mentees + ("ALL", "All") # All mentees in system +] class Question(models.Model): Qname = models.CharField(max_length=200, null=False) topic = models.CharField(max_length=200) - Level = models.CharField(max_length=200) - problemLink =models.URLField(max_length=200) - description= models.CharField(max_length=300,blank=True,null=True) + Level = models.CharField(max_length=200, choices=DIFFICULTY_CHOICES) + problemLink = models.URLField(max_length=200) + description = models.CharField(max_length=300, blank=True, null=True) mentorId = models.IntegerField() - allotedTime= models.DateTimeField(default=timezone.now) - SubmittedAt = models.DateTimeField(default=timezone.now,blank=True) - submitedMentees=models.ManyToManyField(Mentee,blank=True) + scope = models.CharField(max_length=10, choices=SCOPE_CHOICES, default="TEAM") + allotedTime = models.DateTimeField(default=timezone.now) + SubmittedAt = models.DateTimeField(default=timezone.now, blank=True) + submitedMentees = models.ManyToManyField(Mentee, blank=True) def __str__(self): return self.Qname +class QuestionAssignment(models.Model): + question = models.ForeignKey(Question, on_delete=models.CASCADE) + mentee = models.ForeignKey(Mentee, on_delete=models.CASCADE) + assigned_at = models.DateTimeField(auto_now_add=True) + + class Meta: + unique_together = ('question', 'mentee') diff --git a/Questions/views.py b/Questions/views.py index 6c14c63..517e7b9 100644 --- a/Questions/views.py +++ b/Questions/views.py @@ -7,6 +7,8 @@ from django.utils import timezone from clients.models import * import json +from django.db.models import Q + @@ -18,16 +20,27 @@ def QuestionRegister(request): level=data.get('Level') topicss=data.get('topic') topics=topicss.split(" ") + print("=== DEBUG INFO ===") + print("1. RAW DATA:", data) + print("2. DATA TYPES:", {k: type(v) for k, v in data.items()}) serializer = addQuestionSerializer(data=data) + + print("3. IS VALID?", serializer.is_valid()) + print("4. ERRORS:", serializer.errors) # ← THIS TELLS YOU EXACTLY WHY if serializer.is_valid(): serializer.save() mentorId=data.get('mentorId') mentor=Mentor.objects.get(id=mentorId) - mentees = Mentee.objects.filter(mentor_id__in=mentorId) + scope = data.get('scope', 'TEAM') + if scope == 'ALL': + mentees = Mentee.objects.all() + elif scope == 'TEAM': + mentees = Mentee.objects.filter(mentor_id=mentorId) + for mentee in mentees: mentee.total_q+=1 mentee.save() @@ -37,7 +50,6 @@ def QuestionRegister(request): mentor.topic_count[topic]=mentor.topic_count.get(topic,0) + 1 mentor.total_q+=1 mentor.save() - team=Team.objects.get(alloted_mentor=mentor) res_message = "Question added to DB" res_status = status.HTTP_200_OK @@ -68,20 +80,21 @@ def QuestionRegister(request): # ) @api_view(['GET']) -def GetQuestion(request,mentorId): - - question = Question.objects.all().filter(mentorId = mentorId) - res_data = QuestionSerializer(question, many = True, context={'request': request}).data +def GetQuestion(request, mentorId): + # Get mentor's questions OR system-wide questions (logical OR) + question = Question.objects.filter( + models.Q(mentorId=mentorId) | models.Q(scope='ALL') + ) + res_data = QuestionSerializer(question, many=True, context={'request': request}).data - if len(question): + if question.exists(): # Better than len() res_message = "Question data fetched successfully" res_status = status.HTTP_200_OK else: - res_message = "Question does not exist in DB" + res_message = "No questions found" res_status = status.HTTP_404_NOT_FOUND return Response({ - "data": res_data, "message": res_message, "status_code": res_status @@ -202,5 +215,4 @@ def Onsubmit(request): "message": res_msg, "score":score, "status_code": res_status - }, status=res_status) - + }, status=res_status) \ No newline at end of file diff --git a/clients/admin.py b/clients/admin.py index c39582c..5826718 100644 --- a/clients/admin.py +++ b/clients/admin.py @@ -1,9 +1,16 @@ from django.contrib import admin -from .models import * +from .models import Mentor, Mentee, Team -admin.site.register(Mentor) -admin.site.register(Mentee) -admin.site.register(Team) +@admin.register(Mentor) +class MentorAdmin(admin.ModelAdmin): + list_display = ('email', 'name', 'supermentor') + + def get_readonly_fields(self, request, obj=None): + if not request.user.is_superuser: + return ('supermentor',) + return () - \ No newline at end of file + +admin.site.register(Mentee) +admin.site.register(Team) diff --git a/clients/migrations/0007_mentor_supermentor.py b/clients/migrations/0007_mentor_supermentor.py new file mode 100644 index 0000000..10cfcb9 --- /dev/null +++ b/clients/migrations/0007_mentor_supermentor.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.4 on 2026-01-02 17:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("clients", "0006_alter_mentee_image_alter_mentor_image_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="mentor", + name="supermentor", + field=models.BooleanField(default=False, editable=False), + ), + ] diff --git a/clients/migrations/0008_alter_mentor_supermentor.py b/clients/migrations/0008_alter_mentor_supermentor.py new file mode 100644 index 0000000..78f2b2b --- /dev/null +++ b/clients/migrations/0008_alter_mentor_supermentor.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.4 on 2026-01-02 17:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("clients", "0007_mentor_supermentor"), + ] + + operations = [ + migrations.AlterField( + model_name="mentor", + name="supermentor", + field=models.BooleanField(default=False), + ), + ] diff --git a/clients/models.py b/clients/models.py index 3fd5e1b..444a9e2 100644 --- a/clients/models.py +++ b/clients/models.py @@ -3,6 +3,7 @@ from django.contrib.auth.models import AbstractUser from django.core.serializers import serialize from django.contrib.auth.hashers import make_password, check_password + # Create your models here. # Mentor model @@ -45,6 +46,7 @@ class Mentor(models.Model): password = models.CharField(max_length=200,validators=[MinLengthValidator(8)]) branch = models.CharField(max_length=10,choices=Branches) semester = models.IntegerField(validators=[MinValueValidator(1),MaxValueValidator(8)]) + supermentor = models.BooleanField(default=False) phone_number = models.CharField(max_length=10,unique=True) image=models.URLField(null=True,blank=True,default="https://avatar.iran.liara.run/public/8") codechefID = models.URLField(max_length=300,null=True,blank=True) @@ -131,4 +133,3 @@ def __str__(self): return self.team_name - diff --git a/clients/serializers.py b/clients/serializers.py index 07619ad..7a8b8fe 100644 --- a/clients/serializers.py +++ b/clients/serializers.py @@ -7,10 +7,11 @@ class Meta: fields = '__all__' class MentorSerializer(serializers.ModelSerializer): - Mentorteam = TeamDetailSerializer(read_only=True) class Meta: model = Mentor fields = '__all__' + read_only_fields = ['supermentor'] + class MenteeSerializer(serializers.ModelSerializer): Menteeteam = TeamDetailSerializer(read_only=True) @@ -21,9 +22,11 @@ class Meta: #['name','email', 'username', 'password', 'branch', 'semester', 'phone_number', 'codechefID', 'codeforcesID', 'leetcodeID', 'gfgID', 'hackerrankID', 'linkedinID', 'score', 'total_q'] class MentorGetSerializer(serializers.ModelSerializer): Mentorteam = TeamDetailSerializer(read_only=True) + class Meta: model = Mentor - exclude = ['email', 'password','phone_number'] + exclude = ['email', 'password', 'phone_number', 'supermentor'] + class MenteeGetSerializer(serializers.ModelSerializer): Menteeteam = TeamDetailSerializer(read_only=True) @@ -39,7 +42,20 @@ class Meta: class MentorUpdateSerializer(serializers.ModelSerializer): class Meta: model = Mentor - fields = ['image', 'name', 'phone_number', 'password', 'branch', 'semester', 'codechefID', 'codeforcesID', 'leetcodeID', 'gfgID', 'hackerrankID', 'linkedinID'] + fields = [ + 'image', + 'name', + 'phone_number', + 'branch', + 'semester', + 'codechefID', + 'codeforcesID', + 'leetcodeID', + 'gfgID', + 'hackerrankID', + 'linkedinID', + ] + class TeamSerializer(serializers.ModelSerializer): team_members = MenteeGetSerializer(many=True, read_only=True) diff --git a/db.sqlite3 b/db.sqlite3 index 549dce1..a06a633 100644 Binary files a/db.sqlite3 and b/db.sqlite3 differ