2016-10-20 4 views
3

が、私はアプリの調査種類を作成していOrderedDict Djangoの休憩枠組み書き込み可能なネストされたシリアライザを得たので、私はフォームは、[複数の選択肢の質問について] Questiosn、選択肢は予想例えば、

が、私はこのチュートリアルに続く三つのモデルを持っているhttp://www.django-rest-framework.org/api-guide/relations/#nested-relationships

それは1人のレベルのネストされた関係のために正常に動作しますが、2つのレベルのためにそれが

TypeError例外を与える:チョイス "インスタンスが期待さ、OrderedDict([(u'title」、u'option1' )])

を得ました
class ChoiceSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = Choice 
     fields = ['title'] 

class QuestionSerializer(serializers.ModelSerializer): 
    choices = ChoiceSerializer(many=True, required=False) 

    class Meta: 
    model = Question 
    fields = ['title', 'type', 'required','order','choices'] 

    def create(self, validated_data): 
    choices_data = validated_data.pop("choices") 
    question = Question.objects.create(**validated_data) 
    for choice_data in choices_data: 
     Choice.objects.create(question=question, **choice_data) 
    return question 

class FormSerializer(serializers.ModelSerializer): 
    questions = QuestionSerializer(many=True) 

    class Meta: 
    model = Form 
    fields = ['title', 'description', 'created', 'active', 'hash','questions'] 
    read_only_fields = ['active','hash'] 

    def create(self, validated_data): 
    questions_data = validated_data.pop('questions') 
    form = Form.objects.create(**validated_data) 
    for question_data in questions_data: 
     Question.objects.create(form=form, **question_data) 
    return form 

手動の方法を使用して解決

EDIT、FormSerializerでは、メソッドを作成

@transaction.atomic 
    def create(self, validated_data): 
     try: 
      with transaction.atomic(): 
       questions_data = validated_data.pop('questions') 
       form = Form.objects.create(**validated_data) 
       for question_data in questions_data: 
        question = Question.objects.create(form=form, 
                 title=question_data['title'], 
                 type=question_data['type'], 
                 required=question_data['required']) 
        if question.type == Question.RADIO or question.type == Question.CHECKBOX: 
         choices_data = question_data.pop('choices') 
         for choice_data in choices_data: 
          choice = Choice.objects.create(question=question, title=choice_data['title']) 
       return form 
     except Exception, e: 
      raise serializers.ValidationError("Cannot Save Form %s" % e) 
+0

私はこれで任意の場所をつもりではなかったので、私はそれを手動で道をやりました –

答えて

2

をオーバーライドし、私もこれで苦労し、私はこれを処理するための適切な方法があると信じて:

class ChoiceSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = Choice 
     fields = ['title'] 

class QuestionSerializer(serializers.ModelSerializer): 
    choices = ChoiceSerializer(many=True, required=False) 

    class Meta: 
    model = Question 
    fields = ['title', 'type', 'required','order','choices'] 


class FormSerializer(serializers.ModelSerializer): 
    questions = QuestionSerializer(many=True) 

    class Meta: 
    model = Form 
    fields = ['title', 'description', 'created', 'active', 'hash','questions'] 
    read_only_fields = ['active','hash'] 

    def create(self, validated_data): 
     questions_data = validated_data.pop('questions') 
     form = Form.objects.create(**validated_data) 
     for question_data in questions_data: 
      choices_data = question_data.pop('choices') 
      Question.objects.create(form=form, **question_data) 
      for choice_data in choices_data: 
       choice = Choice.objects.create(question=question, **choice_data) 
     return form 

これを台無しにする簡単な方法は、質問オブジェクトを作成する前に選択肢をポップしないことです。あなたがそれを行うと、あなたはinstance expected, got OrderedDict( 500エラーが発生します。あなたはQuestionSerializerに()作成、定義する必要はありませんも

注意。すべての子プロセスは最上位レベルで処理されます。