Вложенные сериализаторы Django с возможностью записи, метод create не работает

У меня есть вложенный сериализатор, метод create не работает. Я искал в интернете и ни один метод не сработал. Самый популярный из них тот, что приведен ниже.

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 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)

распечатки

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')]}

Я передаю сериализатору поле display, которое является идентификатором дисплея. В методе create я нахожу этот дисплей и ссылаюсь на него в новом объекте ad. Поле display присутствует в request.data и передается в сериализатор, но сериализатор жалуется, что поле display отсутствует.

Для поля display, AdsSerializer ожидается следующая структура;

"display": {"id": 91}

тогда как вы посылаете это;

"display": 91

Попробуйте использовать разные сериализаторы для создания и представления.

class AdsCreateSerializer(serializers.ModelSerializer):

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

    display = DisplaySerializer()

    class Meta:
        model = Ads
        fields = "__all__"
Вернуться на верх