I am making a back-end system using DRF in Django. This is my first project in Django and DRF. I am using Django purely as a REST back-end
I am making a quiz/mcq application
This is from my questions app, models.py
from django.db import models
from classifications.models import SubSubCategory
class Question(models.Model):
ANSWER_TYPES = [
('single', 'Single Correct'),
('multiple', 'Multiple Correct'),
]
text = models.TextField()
answer_type = models.CharField(max_length=10, choices=ANSWER_TYPES, default='single')
difficulty = models.CharField(
max_length=10,
choices=[('easy', 'Easy'), ('medium', 'Medium'), ('hard', 'Hard')],
default='medium'
)
explanation = models.TextField(blank=True, null=True)
subsubcategories = models.ManyToManyField(SubSubCategory, related_name='questions', blank=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return 'question'
class Meta:
ordering = ['-created_at']
def correct_options(self):
return self.options.filter(is_correct=True)
def incorrect_options(self):
return self.options.filter(is_correct=False)
class Option(models.Model):
question = models.ForeignKey(Question, related_name='options', on_delete=models.CASCADE)
label = models.CharField(max_length=5)
text = models.TextField()
is_correct = models.BooleanField(default=False)
def __str__(self):
return "options"
I am using Model viewset with router, but here when I try to create question, I have to request in two different endpoints: one for creating question and another for creating options for questions
views.py
from rest_framework import viewsets
from .models import Question, Option
from .serializers import QuestionSerializer, OptionSerializer
from core.permissions import IsAdminOrReadOnlyForAuthenticated
from django.db.models import Q
class OptionViewSet(viewsets.ModelViewSet):
queryset = Option.objects.all()
serializer_class = OptionSerializer
class QuestionViewSet(viewsets.ModelViewSet):
queryset = Question.objects.all()
serializer_class = QuestionSerializer
class SelectViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = QuestionSerializer
queryset = Question.objects.none()
def get_queryset(self):
queryset = Question.objects.all().prefetch_related('subsubcategories')
category_ids = self.request.query_params.getlist('category_id')
subcategory_ids = self.request.query_params.getlist('subcategory_id')
subsubcategory_ids = self.request.query_params.getlist('subsubcategory_id')
category_ids = [int(x) for x in category_ids if x.isdigit()]
subcategory_ids = [int(x) for x in subcategory_ids if x.isdigit()]
subsubcategory_ids = [int(x) for x in subsubcategory_ids if x.isdigit()]
q_filter = Q()
if category_ids:
q_filter |= Q(subsubcategories__subcategory__category__id__in=category_ids)
if subcategory_ids:
q_filter |= Q(subsubcategories__subcategory__id__in=subcategory_ids)
if subsubcategory_ids:
q_filter |= Q(subsubcategories__id__in=subsubcategory_ids)
if q_filter:
queryset = queryset.filter(q_filter)
return queryset.distinct()
What should I do? Change the DB design so that all CRUD can be handled via model view set because currently to do operations of options I am having to request in different endpoint
This is my serializer currently
from rest_framework import serializers
from .models import Question, Option
class OptionSerializer(serializers.ModelSerializer):
class Meta:
model = Option
fields = ('label','text','id')
class QuestionSerializer(serializers.ModelSerializer):
options = OptionSerializer(many=True)
class Meta:
model = Question
fields = ('id', 'text', 'answer_type', 'difficulty', 'explanation', 'subsubcategories', 'options')
Or do I have to write custom implementation for CRUD for options inside question