django: how to pass condition to .is_valid() without populating all serializers parameters

Question:

From the frontend, it was necessary to get the question object in order to understand what to return in the get function from the frontend, a request is sent to the post function With the id of the object to be returned.

With class TestQuestionList
in the post function I don’t need to create a new object, so I don’t fill in the fields, image, answers in the request, but django requires me to fill in these fields and returns – bad request 400
"POST /api/questions/ HTTP/1.1" 400 85

views.py:

class TestQuestionList(APIView):
    def __init__(self):
        self.questions = [1]
    def get(self, request):
        romms = TestQuestionBlok.objects.filter(id__in=self.questions)
        serializer = TestQuestionSerializers(romms, many=True)
        return Response(serializer.data)
    def post(self, request, format=None):
        serializer1 = TestQuestionSerializers(data=request.data)
        if serializer1.is_valid() :
            self.questions = serializer1.data['questions']
            return Response(serializer1.data, status=status.HTTP_200_OK)
        return Response(serializer1.errors, status=status.HTTP_400_BAD_REQUEST)

serializers.py:

class TestQuestionSerializers(serializers.ModelSerializer):

    class Meta:
        model = TestQuestionBlok
        fields = ('__all__')

models.py:

class TestQuestionBlok(models.Model):
    image = models.ImageField(upload_to='questionsImages/')
    answers = models.ManyToManyField(TestAnswers)
    question = models.CharField(max_length=300)

    def __str__(self):
        return self.question

How can I bypass these requirements?

Asked By: Vahe Hakobjanyan

||

Answers:

Your API should look like this in order to get several objects:

class YourAPI(APIView):
    class InputSerializer(serializers.Serializer):
        ...

        objects = serializers.PrimaryKeyRelatedField(
            queryset=YourResourceModel.objects.all(),
            required=False,
            allow_empty=True,
            allow_null=True
        )

        ...
    class OutputSerializer(serializers.ModelSerializer):
        class Meta:
            model = TestQuestionBlok
            fields = ('__all__')
    
    def post(self, request):
        serialzier = self.InputSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        
        return Response(serializer.validated_data)

The serializers do not have to be part of your API it is just an example. However, it is a good practice according to some style guides.

Check out PrimaryKeyRelatedField

Essentially, your FE passes the PKs of the objects that you need as an array to the BE in a variable called objects, you can call it whatever you want.

Answered By: antpngl92