как создать несколько объектов одним запросом DRF - PullRequest
1 голос
/ 07 марта 2020

У меня есть следующие модели

class Product(models.Model):
    name = models.CharField(null=True, blank=True, max_length=500)
    category = models.CharField(null=True, blank=True, max_length=120)


class SpecificationName(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, null=True, related_name='specifications')
    name = models.CharField(max_length=125)

class Attribute(models.Model):
    spec_name = models.ForeignKey(SpecificationName, on_delete=models.CASCADE, null=True, related_name='attributes')
    index = models.CharField(max_length=200, blank=True, null=True)
    value = models.CharField(max_length=250, blank=True, null=True)

после сохранения объектов в Django admin У меня есть пример

{
    "name": "Apple Smart Watch",
    "category": "IT",
    "specifications": [
        {
            "name": "Test Data",
            "attributes": [
                {
                    "index": "test",
                    "value": "test2"
                },
                {
                    "index": "test7",
                    "value": "test8"
                },
                {
                    "index": "test9",
                    "value": "test10"
                }
            ]
        },
        {
            "name": "Test Data Continued",
            "attributes": [
                {
                    "index": "bla",
                    "value": "bla1"
                },
                {
                    "index": "bla 2",
                    "value": "bla 4"
                },
                {
                    "index": "test9",
                    "value": "test10"
                }
            ]
        },
        {
            "name": "Test Spec",
            "attributes": []
        }
    ]
}

Мне нужно сохранить объект такого типа одним запросом, но Я не могу сделать это

мой сериализатор выглядит так

class ProductSerializer(serializers.ModelSerializer):
    specifications = SpecNameSerializer(many=True)
    # attributes = AttributeSerializer(many=True, required=False)

class Meta:
    model = Product
    fields = ['name', 'category', 'brand', 'price', 'specifications']

def create(self, validated_data):
    specs = validated_data.pop('specifications')
    instance = Product.objects.create(**validated_data)

    for spec in specs:
        SpecificationName.objects.create(product=instance, **spec)
        print(spec)

    return instance

с этим кодом, я получаю следующий результат, но не так, как ожидалось

{
    "name": "Appel watch series",
    "specifications": [
        {
            "name": "Test Data",
            "attributes": []
        },
        {
            "name": "Test Data comn",
            "attributes": []
        },
        {
            "name": "Test Spec",
            "attributes": []
        }
    ]
}

it не могу писать в атрибуты

Я искал много ответов, но не нашел и не применил некоторые из них, опять же, это не помогло мне. Я использую только ListCreateView в представлениях. Пожалуйста, есть кто-нибудь, кто может помочь решить эту проблему. Заранее спасибо!

1 Ответ

0 голосов
/ 11 марта 2020

решено

Я использую здесь ModelSerializer вместо этого я использовал Serializer и добавил некоторые изменения здесь мой ответ, и это сработало

class AttributeSerializer(serializers.Serializer):
    index = serializers.CharField(max_length=200)
    value = serializers.CharField(max_length=200)


class SpecNameSerializer(serializers.ModelSerializer):
    attributes = AttributeSerializer(many=True)

    class Meta:
        model = SpecificationName
        fields = '__all__'


class ProductSerializer(serializers.ModelSerializer):
    specifications = SpecNameSerializer(many=True)


    class Meta:
        model = Product
        fields = ['name', 'category', 'brand', 'price', 'specifications']


    def create(self, validated_data):
        specs = validated_data.pop('specifications')
        instance = Product.objects.create(**validated_data)

        for spec in specs:
            SpecificationName.objects.create(product=instance, **spec)
            attrs = spec.pop('attributes')
            for attr in attrs:
                Attribute.objects.create(spec_name=spec, **attr)

        return instance
...