Django Rest-Framework Nested Serializers

Django, Flask, Bottle, WSGI, CGI…
Antworten
Freumel
User
Beiträge: 69
Registriert: Donnerstag 25. Januar 2018, 13:47

Hallo zusammen,

ich habe folgenden Serializer:

Code: Alles auswählen

class AnswerSerializer(serializers.ModelSerializer):
    question = QuestionSerializer()
    class Meta:
        model = Answer
        fields = '__all__'

        extra_kwargs = {
            'id':{'read_only':True},
            'key':{'read_only':True},
        }

    def create(self,validated_data):
        new_answer = Answer.objects.create(
            question=validated_data['question'],
            user=validated_data['user']
        )

        return new_answer
Nun möchte ich eine Answer erstellen:

Code: Alles auswählen

@api_view(['POST',])
def create_question_answer(request):
    answer_serializer = AnswerSerializer(
        data=request.data
    )

    if answer_serializer.is_valid():
        answer_serializer.save()
        return Response(
            answer_serializer.data,
            status=status.HTTP_201_CREATED
        )

    return Response(
        {'err':answer_serializer.errors},
        status=status.HTTP_400_BAD_REQUEST
    )
Der JSONBody dazu sieht so aus:

Code: Alles auswählen

{
	"question":1,
	"user":1
}
Nun ist es so, dass ich mit einem "Nested Serializer" arbeite.
Es wird anstelle von questions als id ein dictionary benötigt. Sehe ich ein:

Code: Alles auswählen

@api_view(['POST',])
def create_question_answer(request):
    question = get_object_or_404(
        Question,
        id=request.data['question']
    )
    request.data['question']=QuestionSerializer(question).data

    answer_serializer = AnswerSerializer(
        data=request.data
    )

    if answer_serializer.is_valid():
        answer_serializer.save()
        return Response(
            answer_serializer.data,
            status=status.HTTP_201_CREATED
        )

    return Response(
        {'err':answer_serializer.errors},
        status=status.HTTP_400_BAD_REQUEST
    )
In dem Zuge, falls interessant natürlich noch den Question Serializer:

Code: Alles auswählen

class QuestionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Question
        fields = '__all__'

        extra_kwargs = {
            'id':{'read_only':True},
        }
    
    def create(self, validated_data):
        new_question = Question.objects.create(
            title=validated_data['title']
        )

        return new_question
Und jetzt endlich zur Frage:
Ich habe bei dem Model Questions im Titel einen unique=True (zum Glück!) - denn so kriege ich folgendes Feedback beim Aufruf der create_answer Methode:

Code: Alles auswählen

"question": {
        "non_field_errors": [
            "question with this title already exists."
        ]
 }
Die Eingabe ist Valide, allerdings wird scheinbar versucht eine Frage mit zu erstellen.
Ich möchte gerne eine Antwort zu einer Frage erstellen, und die Frage als Serializer mit bei der Antwort dazu geben.
Nun frage ich mich, wie ich das am besten mache. Natürlich kann ich einen ReadOnly und einen WriteOnly Serializer separat voneinander erstellen.
Allerdings schreibe ich meinen Code nicht gerne doppelt. Da muss es doch eine bessere Möglichkeit geben eine Antwort zu erstellen, ohne eine Frage gleichzeitig mit erstellen zu müssen oder zwei separate Methoden zu definieren.

Hat da jemand einen Ratschlag?

Vielen Dank!
Antworten