Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 如何在保存模型实例时保证嵌套对象的原子性?_Django_Validation_Django Rest Framework - Fatal编程技术网

Django 如何在保存模型实例时保证嵌套对象的原子性?

Django 如何在保存模型实例时保证嵌套对象的原子性?,django,validation,django-rest-framework,Django,Validation,Django Rest Framework,这是我的密码: from django.db import models class Car(models.Model): is_crawler = models.BooleanField() class Wheel(models.Model): car = models.ForeignKey(A, related_name='wheels', on_delete=models.CASCADE) radius = models.IntegerField() cl

这是我的密码:

from django.db import models

class Car(models.Model):
    is_crawler = models.BooleanField()


class Wheel(models.Model):
    car = models.ForeignKey(A, related_name='wheels', on_delete=models.CASCADE)
    radius = models.IntegerField()


class WheelSerializer(serializer.ModelSerializer):
    class Meta:
        model = Wheel
        fields = '__all__'


class CarSerializer(serializers.ModelSerializer):
    wheels = WheelSerializer(many=True)
    
    class Meta:
        model = Car
        fields = '__all__'
        
    def validate(self, attrs):
        is_crawler = attrs.get('is_crawler')
        wheels_data = attrs.get('wheels')
        if wheels_data and is_crawler:
            raise ValidationError("Crawler can't have wheels")

    def create(self, validated_data):
        is_crawler = attrs.get('is_crawler')
        wheels_data = attrs.get('wheels')
        car = Car.objects.create(**validated_data)
        for wheel_data in wheels_data:
            wheel_serializer = WheelSerializer(**wheel_data)
            if wheel_serializer.is_valid():
                wheel_serializer.save()
        return car
所以,当我试图发送类似

{“is_crawler”:true,“wheels”:[{“radius”:5}]}
对于CarSerializer,它将引发ValidationError,从而从视图中引发400响应


但它并不禁止在admin中为爬虫程序创建轮子。是否有一种方法可以将验证从序列化程序转移到模型的
clean
save
方法,以禁止创建带轮子的履带车或在代码的任何部分向履带车添加轮子?如果有,它会在DRF中引发相同的ValidationError并从DRF返回HTTP_400吗?

您可以向模型中添加
clean
方法,但不会在序列化程序中调用它。这是为了分离关注点,如中所述

这是您在
汽车
车轮
上使用清洁方法的代码,并对其进行了一些小的更改,以使其在我这边工作

等级车(型号.型号):
is_crawler=models.BooleanField()
def清洁(自清洁):
如果self.is_爬虫和self.wheels.count():
raise ValidationError(“爬虫程序不能有轮子”)
类车轮(型号.型号):
car=车型.ForeignKey(汽车,相关的_name=“车轮”,在_delete=车型.CASCADE上)
radius=models.IntegerField()
def清洁(自清洁):
如果self.car.is_爬虫:
raise ValidationError(“爬虫程序不能有轮子”)
类序列化程序(serializers.ModelSerializer):
类元:
型号=车轮
fields=“\uuuu all\uuuuuu”
只读字段=(“汽车”)
类CarSerializer(serializers.ModelSerializer):
wheels=WheelSerializer(多个=真)
类元:
型号=汽车
fields=“\uuuu all\uuuuuu”
def验证(自身、属性):
is\u crawler=attrs.get(“is\u crawler”)
wheels\u data=attrs.get(“车轮”)
如果是数据,并且是爬虫程序:
raise ValidationError(“爬虫程序不能有轮子”)
返回属性
def创建(自我验证的_数据):
wheels\u data=已验证的\u data.pop(“wheels”)
car=car.objects.create(**已验证的_数据)
对于wheels_数据中的wheels_数据:
车轮=车轮。对象。创建(**wheel\u数据,汽车=汽车)
汽车.车轮.添加(车轮)
回程车
正如文档中所说的,您还可以在序列化程序的
验证
方法中实例化您的模型,但不鼓励这样做

def验证(自身、属性):
实例=示例模型(**attrs)
instance.clean()
返回属性