简体   繁体   中英

Django Rest Framework - wrong data validating with nested serializer

Models:

class Section(models.Model):
    name = models.CharField(max_length=50)
    building = models.ForeignKey(Building, related_name='sections', on_delete=models.CASCADE)

class Standpipe(models.Model):
    name = models.CharField(max_length=50)
    section = models.ForeignKey(Section, related_name='pipes', on_delete=models.CASCADE)

Serializers:

class StandpipeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Standpipe
        fields = '__all__'


class SectionSerializer(serializers.ModelSerializer):
    pipes = StandpipeSerializer(many=True, required=False)

    class Meta:
        model = Section
        fields = ('name', 'building', 'pipes')

    def create(self, validated_data):
        pipes_data = validated_data.pop('pipes')
        section = Section.objects.create(**validated_data)
        for pipe_data in pipes_data:
            Standpipe.objects.create(section=section, **pipe_data)
        return section

View is just a regular ModelViewSet. I didn`t override any methods.

I send this data in request:

{
  'name': 'One',
  'building': 1,
  'pipes': [
      {'name': 'PipeOne'},
      {'name': 'PipeTwo'},
   ]
}

But in validated data i get only

{'name': 'One', 'building': <Building: Building object (1)>}

In serializer initial data we can see:

<QueryDict: {'name': ['One'], 'building': ['1'], 'pipes': ["{'name': 'PipeOne'}", "{'name': 'PipeTwo'}"]}>

If i try to get key 'pipes' from initial dict i get only second dict

"{'name': 'PipeTwo'}"

AND only in string format. If i remove 'required=False' from it, i get an error:

{'pipes': [ErrorDetail(string='This field is required.', code='required')]}

Cant understand why it goes wrong. I tried to use solution from the documentation

The problem was with my test case. I sent data using drf 'APITestCase'. Code looked like:

 response_section = self.client.post(url_section, data={'name': 'One',
                                                        'building': response_building.data['id'],
                                                        'pipes': [
                                                               {'name': 'PipeOne'},
                                                               {'name': 'PipeTwo'}]
                                                        })

So the solution is to add

format='json'

So now it looks like

 response_section = self.client.post(url_section, data={'name': 'One',
                                                        'building': response_building.data['id'],
                                                        'pipes': [
                                                               {'name': 'PipeOne'},
                                                               {'name': 'PipeTwo'}
                                                           ]
                                                           }, format='json')

And works fine

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM