set two fields in the serializer, one with the objects only read, and other
to write. Like this
class ChapterSerializer(ModelSerializer):
uuid = UUIDField(read_only=False)
sections_obj = SectionSerializer(many=True, read_only=True,
source='sections')
class Meta:
model = Chapter
fields = ('uuid', 'description', 'sections', 'sections_obj')
This way you have a serializer nested read/write. You serializer pass the
validation and you manipulate the data in the method create.
Sry my English, I hope you understandme.
On Monday, September 4, 2017 at 12:58:08 PM UTC-3, Markus Hubig wrote:
>
> I'm having a problem creating (nested) serializers for the following
> models:
>
> 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)
>
>
> Here is the serializer for the Chapter model with the create method:
>
> 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
>
>
> And here are two slightly different variants of the Section serializer:
>
> 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')
>
>
> Now if I try to create a new Chapter with nested Sections and the
> PrimaryKeyRelatedField in the Section serializer has the queryset parameter
> set, I get the following error:
>
> 'sections': [{'chapter': ['Invalid pk "x" - object does not exist.']}]
>
> I think this error is created while converting the pk to an internal value
> <https://github.com/encode/django-rest-framework/blob/master/rest_framework/relations.py#L250>
> but
> actually sounds more like a validation error ...
>
>
> If I use the variant with the read_only=true parameter, creating a new
> Chapter with nested Sections works, but now I can no longer create a new
> Section (Chapter field is set to an existing Chapter UUID) because the
> chapter field is removed while validating the input data.
>
> django.db.utils.IntegrityError: null value in column "chapter_id" violates
> not-null constraint
>
>
> I think I could solve this by duplicating the SectionSerializer, but this
> seems to be a very crude solution ...
>
>
> Overall my experience implementing Nested Serializers with DRF is very
> frustrating! I think one major problem is, that there are very limited
> documentation on this topic! Especially the validation steps are very
> unintuitive, as can be seen in the example above:
>
>
> - Why is the validation step not skipped if I overwrite the validate
> methode?
> - Why is the pk checked while converting to an internal value?
> - Why are read_only fields obmitted (even within the input data to
> self.validate!!!!!) and what can I do about this?
> - How is the internal validation api working? There are many
> methods like run_validation, run_validators, to_internal_value,
> validate, validate_empty_values, validators. How are they working
> together?
> (Any why are they always getting in my way?)
>
>
--
You received this message because you are subscribed to the Google Groups
"Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.