Django(DRF)Serializer插入NULL

时间:2018-03-21 02:53:13

标签: python mysql django django-rest-framework

我遇到了Django的问题,我试图在MySQL数据库中插入一个新行而不为未指定的数据提供NULL。

例如,请考虑以下事项:

class MyModel(models.Model):
    class Meta:
        db_table = 'model_table'
        managed = False

    a = models.AutoField(primary_key=True)
    b = models.CharField(max_length=255)
    c = models.CharField(max_length=255, blank=True)

将以下数据提供给Serializer以进行save():

    data = list()
    data['b'] = 'Some Text'
    serializer = serializers.MyModelSerializer(data=data)
    serializer.save()

生成的SQL对于每个未指定的字段都为NULL,在本例中为“c”。数据库中的表不允许NULL,但具有默认值来处理未指定的数据。

是否有可能覆盖此序列化程序功能以允许在尝试插入时完全省略字段,或者我是否必须创建一个省略了这些字段的新模型,并为此特定情况创建一个“创建”模型对这些领域有什么了解吗?

注意:序列化程序在其fields变量中只有字段“b”,因此它不会立即意识到“c”列。

编辑:为了尝试澄清一点,这是由于列中不允许空值而生成的SQL失败。但是'c'确实有默认值。

INSERT INTO `model_table` (`b`, `c`) VALUES ('Some Text', NULL)

对于'a'PK的AutoField来说没问题,默认情况下省略,但由于提供给序列化程序的数据中没有提供值,'c'被替换为NULL,而不是从完全是SQL。作为一种解决方法,我复制了模型并删除了我不需要的字段只是为了让它工作,并且生成的SQL是有效的,因为模型本身不知道列,但这似乎不像这样做的最好方法。以下是我想要此模型和序列化程序组合输出

的内容
INSERT INTO `model_table` (`b`) VALUES ('Some Text')

这样就可以为'c'提供MySQL本身提供的默认列值。当我没有向序列化程序提供任何数据时,模型和序列化程序可以插入NULL,这是问题所在。

2 个答案:

答案 0 :(得分:0)

你可以覆盖序列化器创建方法,如下面的

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

答案 1 :(得分:0)

这是因为您将c定义为blank=True。 如果您确实希望c有时候NULL,则必须将其定义如下,
c = models.CharField(max_length=255, blank=True, null=True)

请参阅有关Diifference between null=True and blank=True in Django 的StackOverflow帖子

从POST

null用于DataBase列值

null=True在您的数据库中的列上设置NULL(与NOT NULL)。 Django字段类型(如DateTimeFieldForeignKey)的空白值将作为NULL存储在数据库中。

blank用于表单中的字段要求

blank=True确定表单中是否需要该字段。这包括管理员和您自己的自定义表单。如果blank=True则不需要该字段,而如果False该字段不能为空。