2017-09-04 18 views
0

我有以下型號創建(嵌套)序列化問題可寫嵌套串行器:與PrimaryKeyRelatedField

class Chapter(Model): 
    uuid = UUIDField(primary_key=True, editable=False) 
    description = TextField(blank=True) 

class Section(Model): 
    uuid = UUIDField(primary_key=True, editable=False) 
    description = TextField(blank=True) 
    chapter = ForeignKey(Chapter, related_name='sections', on_delete=CASCADE) 

下面是章模型創建方法串行:

class ChapterSerializer(ModelSerializer): 
    uuid = UUIDField(read_only=False) 
    sections = SectionSerializer(many=True, read_only=False) 

    class Meta: 
     model = Chapter 
     fields = ('uuid', 'description', 'sections') 

    def create(self, validated_data): 
     sections = validated_data.pop('sections', []) 
     chapter = Chapter.objects.create(**validated_data) 

     for section in sections: 
      section.update({'chapter': chapter}) 
      section = Section.objects.create(**section) 

     return chapter 

這裏有兩個稍微不同的部分串化器變體:

class SectionSerializer(ModelSerializer): 
     uuid = UUIDField(read_only=False) 
     chapter = PrimaryKeyRelatedField(read_only=true) 

     class Meta: 
      model = Section 
      fields = ('uuid', 'description', 'chapter') 

class SectionSerializer(ModelSerializer): 
     uuid = UUIDField(read_only=False) 
     chapter = PrimaryKeyRelatedField(queryset=Chapter.objects.all()) 

     class Meta: 
      model = Section 
      fields = ('uuid', 'description', 'chapter') 

現在,如果我嘗試創建該科串行與嵌套的區段新的篇章和PrimaryKeyRelatedFieldqueryset參數設置,我得到以下錯誤:

'sections': [{'chapter': ['Invalid pk "x" - object does not exist.']}] 

如果我用了read_only=true參數的變異,產生一個帶有嵌套節的新章節可以工作,但是現在我不能再創建一個新的節(章節字段被設置爲現有的章節UUID),因爲在驗證輸入數據的同時刪除了章節字段。

django.db.utils.IntegrityError: null value in column "chapter_id" violates not-null constraint 

我想我可以通過複製SectionSerializer解決這個問題,但是這似乎是一個非常粗略的解決方案...

任何人都知道一個更好的方法嗎?

回答

0

OK,回答我的問題:

我終於找到一種方式來獲得一個「嵌套」,沒有代碼重複「可寫」的版本SectionSerializer的:

class NestedSectionSerializer(ModelSerializer): 
    uuid = UUIDField(read_only=False) 

    class Meta: 
     model = Section 
     exclude = ('chapter',) 

class SectionSerializer(NestedSectionSerializer): 
    url = serializers.HyperlinkedIdentityField(view_name='section-detail') 

    class Meta: 
     model = Section 
     fields = '__all__' 

class ChapterSerializer(ModelSerializer): 
    url = serializers.HyperlinkedIdentityField(view_name='chapter-detail') 
    uuid = UUIDField(read_only=False) 
    sections = NestedSectionSerializer(many=True, read_only=False) 

    class Meta: 
     model = Chapter 
     fields = '__all__' 

    def create(self, validated_data): 
     sections = validated_data.pop('sections', []) 
     chapter = Chapter.objects.create(**validated_data) 

     for section in sections: 
      section.update({'chapter': chapter}) 
      section = Section.objects.create(**section) 

     return chapter 

這裏的關鍵IST在「嵌套」序列化器中明確排除對chapter的敬畏,但將其再次添加到「可寫入」序列化器中。這甚至可以擴展到深層嵌套結構!

而通過使用繼承,我可以避免大多數代碼重複。

相關問題