[Answered ]-How to make a field the same as int:pk in django rest framework?

1👍

You can mark the question as a read_only=True field:

class AnswerQuestionsSerializer(serializers.ModelSerializer):
    user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())
    question = serializers.PrimaryKeyRelatedField(read_only=True)

    class Meta:
        model = Answer
        fields = ('answer', 'user', 'question', 'number_of_points', 'moderate_status',)

and in the view inject it in the create method of the serializer:

class AnswerQuestions(generics.CreateAPIView, generics.GenericAPIView):
    queryset = Answer.objects.all()
    serializer_class = AnswerQuestionsSerializer

    def perform_create(self, serializer):
        return serializer.save(user=self.request.user, question_id=self.kwargs['pk'])

    def get_queryset(self):
        return super().get_queryset().filter(
            question_id=self.kwargs['pk']
        )

You could work with a mixin, something like:

class ParentKeyAPIView:
    parent_url_pk = 'pk'
    parent_model_field = None

    def perform_create_kwargs(self, **kwargs):
        kwargs[self.parent_model_field] = self.kwargs[self.parent_url_pk]
        return kwargs

    def perform_create(self, serializer):
        return serializer.save(**self.perform_create_kwargs())

    def get_queryset(self):
        return super().get_queryset().filter(
            **{self.parent_model_field: self.kwargs[self.parent_url_pk]}
        )

Then you can use such mixin as:

class AnswerQuestions(ParentKeyAPIView, generics.CreateAPIView):
    model = Answer
    parent_model_field = 'question_id'
    serializer_class = AnswerQuestionsSerializer

    def perform_create_kwargs(self, **kwargs):
        return super().perform_create_kwargs(user=self.request.user, **kwargs)

Then the mixin will at least take care both of the filtering and the creation of the object.

Leave a comment