In my API, I have two models Question
and Option
as shown below
class Question(models.Model):
body = models.TextField()
class Options(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
option = models.CharField(max_length=100)
is_correct = models.SmallIntegerField()
While creating a question it would be nicer the options can be created at the same time. And already existed question should not be created but the options can be changed if the options are different from previous.
I am using ModelSerializer
and ModelViewSet
. I use different urls and views for Question
and Option
.
serializers.py
class QuestionSerializer(serializers.ModelSerializer):
class Meta:
model = Question
fields = '__all__'
class OptionReadSerializer(serializers.ModelSerializer):
question = QuestionSerializer(read_only=True)
class Meta:
model = Option
fields = ('question', 'option', 'is_correct')
class OptionWriteSerializer(serializer.ModelSerializer):
class Meta:
model = Option
fields = ('question', 'option', 'is_correct')
views.py
class QuestionViewSet(ModelViewSet):
seriaizer_class = QuestionSerializer
queryset = Question.objects.all()
class OptionViewSet(ModelViewSet):
queryset = Option.objects.all()
def get_serializer_class(self):
if self.request.method == 'POST':
return OptionWriteSerializer
return OptionReadSerializer
urls.py
from django.urls import include
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('api/question', QuestionViewset, base_name='question')
router.register('api/option', OptionViewSet, base_name='option')
urlpatterns = [
path('', include(router.urls))
]
In this way, I always have to create questions first and then I can individually add the option for that question. I think this may not be a practical approach.
It would be nicer that question and option can be added at the same time and similar to all CRUD operations.
The expected result and posting data in JSON format are as shown below:
{
"body": "Which country won the FIFA world cup 2018",
"options": [
{
"option": "England",
"is_correct": 0
},
{
"option": "Germany",
"is_correct": 0
},
{
"option": "France",
"is_correct": 1
}
]
}