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?
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.
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?
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.