当前位置:网站首页>drf 接收嵌套数据并创建对象, 解决:drf NOT NULL constraint failed

drf 接收嵌套数据并创建对象, 解决:drf NOT NULL constraint failed

2022-06-12 21:23:00 阿狸的情书

一、情景再现

我建立一个userinfo表,并且外键连接user表,在serializers类中实现了正向嵌套,我目的是想接收用户的json数据实现自动创建UserInfo对象,并保存到数据库中。

我将配置信息放出来,这是可能影响程序运行的因素:
Django 4.0.3 4.0.4
django-filter 21.1 21.1
djangorestframework-simplejwt 5.2.0 5.2.0
django-cors-headers 3.12.0 3.12.0
djangorestframework 3.13.1 3.13.1

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } }

二、事故现场

models.py

class UserInfo(models.Model):
    personInfo = models.ForeignKey(User, on_delete=models.CASCADE)
    days = models.IntegerField()
    progress = models.IntegerField()
    pub_date = models.DateTimeField('date published', null=True)
    recitation = models.ManyToManyField(to='Word', verbose_name='已背单词', null=True)

serializers.py

class UserInfoSerializer(serializers.ModelSerializer):
    personInfo = UserSerializer()

    class Meta:
        model = UserInfo
        fields = ['personInfo', 'days', 'progress', 'pub_date', 'recitation']

    def create(self, validated_data):
        profile_data = validated_data.pop('personInfo')
        userinfo = UserInfo.objects.create(**validated_data)
        User.objects.create(personInfo=userinfo, **profile_data)
        return userinfo

三、查官方文档

官方关于为嵌套法写create方法的例子

Writing .create() methods for nested representations
If you’re supporting writable nested representations you’ll need to write .create() or .update() methods that handle saving multiple objects.

The following example demonstrates how you might handle creating a user with a nested profile object.

class UserSerializer(serializers.ModelSerializer):
    profile = ProfileSerializer()

    class Meta:
        model = User
        fields = ['username', 'email', 'profile']

    def create(self, validated_data):
        profile_data = validated_data.pop('profile')
        user = User.objects.create(**validated_data)
        Profile.objects.create(user=user, **profile_data)
        return user

四、问题解决

可能是官网文档和我的情况不太一样,也许是用了jwt的原因。
报错:NOT NULL constraint failed

将官网文档给的create方法中的user = User.objects.create(**validated_data)这一行改为:user_obj, created = User.objects.get_or_create(**user_dict)解决。

改正后的代码:

models.py

class UserInfo(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    days = models.IntegerField()
    progress = models.IntegerField()
    pub_date = models.DateTimeField('date published', null=True)
    recitation = models.ManyToManyField(to='Word', verbose_name='已背单词', null=True)

    def __str__(self):
        return self.user.username

    class Meta:
        ordering = ['pub_date']

serializers.py

class UserInfoSerializer(serializers.ModelSerializer):
    user = UserSerializer()

    class Meta:
        model = UserInfo
        fields = ['user', 'days', 'progress', 'pub_date', 'recitation']

    def create(self, validated_data):
        user_dict = validated_data.pop('user')
        user_obj, created = User.objects.get_or_create(**user_dict)
        return UserInfo.objects.create(user=user_obj, **validated_data)

原网站

版权声明
本文为[阿狸的情书]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_17802895/article/details/125078220