Home > Back-end >  Django writable nested serializers, create method not working
Django writable nested serializers, create method not working

Time:12-05

I have a nested serializer, the create method does not work. I have searched over the internet and no method worked for me. The most popular one is the one listed below.

models.py



class Displays(models.Model):
    id = models.CharField(primary_key=True, max_length=32,
                          default=generate_uuid)
    name = models.CharField(max_length=45, blank=True, null=True)


class OrdersDj(models.Model):
    id = models.CharField(primary_key=True, max_length=32,
                          default=generate_uuid)

class AdsDj(models.Model):
    id = models.CharField(primary_key=True, max_length=32,
                          default=generate_uuid)
    order = models.ForeignKey(
        OrdersDj, on_delete=models.CASCADE, blank=False, null=True)
    display = models.ForeignKey(
        Displays, on_delete=models.CASCADE, blank=True, null=True)

serializers.py


class DisplaySerializer(serializers.ModelSerializer):

    class Meta:
        model = Displays
        fields = "__all__"

class AdsSerializer(serializers.ModelSerializer):

    display = DisplaySerializer()

    def create(self, validated_data):
        print("validated_data", validated_data)
        display_id = validated_data.pop('display')
        display = Displays.objects.get(id=display_id)
        ad = Displays.objects.create(display=display, **validated_data)
        return ad

    class Meta:
        model = Ads
        fields = "__all__"


class OrderSerializer(serializers.ModelSerializer):

    ads = AdsSerializer(source="adsdj_set", many=True)

    def create(self, validated_data):
        validated_data.pop('adsdj_set')
        order = Orders.objects.create(**validated_data)
        return order

    class Meta:
        model = Orders
        fields = "__all__"

views.py

class AdsCreate(APIView):

    def put(self, request):
        print('request.data', request.data)
        serializer = serializers.AdsSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            print('serializer.data > serializer.valid', serializer.data)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        print('serializer.errors > serializer.invalid', serializer.errors)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

print outs

request.data <QueryDict: {'order': ['18bb2225cf6e407a943f2941072d06de'], 'display': ['91'], 'firstday': ['2021-12-4'], 'lastday': ['2021-12-21'], 'duration': ['17'], 'filetype': ['image/png'], 'originalname': ['Picture1.png'], 'price': ['2550'], 'status': ['0'], 'filehash': ['not available yet'], 'orderByNum': ['-1'], 'imgWidth': ['1061'], 'imgHeight': ['708'], 'image': [<InMemoryUploadedFile: Picture1.png (image/png)>]}>

serializer.errors > serializer.invalid {'display': [ErrorDetail(string='This field is required.', code='required')]}

I am giving the display field to the serializer that is the id of the display. In the create method I find that display and reference it in the new ad object. The display field is present in the request.data and passed to the serializer, the serializer complains that the display field is not present.

One version of sending json data

{"order":"18bb2225cf6e407a943f2941072d06de","display":{"id":91},"firstday":"2021-12-5","lastday":"2021-12-15","duration":11,"image":{},"filetype":"image/png","originalname":"Picture1.png","price":1650,"status":0,"filehash":"not available yet","orderByNum":-1,"imgWidth":1061,"imgHeight":708}

CodePudding user response:

Try using different serializers for creation and representation.

class AdsCreateSerializer(serializers.ModelSerializer):

    class Meta:
        model = Ads
        fields = "__all__"
class AdsSerializer(serializers.ModelSerializer):

    display = DisplaySerializer()

    class Meta:
        model = Ads
        fields = "__all__"

CodePudding user response:

For display field, AdsSerializer expects the following structure;

"display": {"id": 91}

whereas you send this;

"display": 91
  • Related