如何将空值存储为整数字段

Posted

技术标签:

【中文标题】如何将空值存储为整数字段【英文标题】:How to store empty value as an Integerfield 【发布时间】:2013-12-22 09:02:45 【问题描述】:

我已经看到了所有类似的线程,阅读了文档,并尝试了许多组合以在 db 中将空值存储为 IntegerField 并且每次都失败。

我正在使用 mysql

我的models.py 定义了一个age=models.IntegerField() 字段。我从 csv 文件填充 db,有些单元格没有价值。 Django 文档说:

Field.null

If True, Django will store empty values as NULL in the database. Default is False.
Note that empty string values will always get stored as empty strings, not as NULL. 

由于我正在使用IntegerField,我希望将一个空字符串(csv 中的一个空单元格)存储为 db 中的NULL。因此,我(认为)必须将null=True 添加到age 字段。实际上,我已经尝试了更多:

age=models.IntegerField()
age=models.IntegerField(null=True)
age=models.IntegerField(null=True, blank=True)
age=models.IntegerField(null=True, blank=True, default=None)

每次我向数据库插入一个空字符串时,我都会得到

ValueError: invalid literal for int() with base 10: ''

你猜我还能做什么?

【问题讨论】:

是的!也是我的问题! 【参考方案1】:

字符串不是整数;并且空白字符串不是NoneNULL。您需要做的是捕获那些字段为空白的实例,然后将其转换为None

foo = "something" # "something" is coming from your CSV file

try:
   val = int(foo)
except ValueError:
   # foo is something that cannot be converted to
   # a number. It could be an empty string, or a
   # string like 'hello'
   # provide a default value
   val = None

# Now use val to insert into the database
f = MyModel()
f.age = val
f.save()

blank 严格用于前端验证;它对数据库端没有任何影响:

请注意,这与null 不同。 null 纯属 与数据库相关,而 blank 与验证相关。如果一个字段 有blank=True,表单验证将允许输入一个空值。 如果字段有blank=False,则该字段为必填项。

另一方面,null 与数据库有关:

如果为 True,Django 会将空值作为 NULL 存储在数据库中。默认为 False。

IntegerField 需要可以转换为整数的值,因此当您传入 空白字符串 时,它无法转换它并引发异常。相反,如果你传入None,并且你有age = models.IntegerField(null=True),它知道正确存储它。

总结一下:

age = models.IntegerField()

字段是必需的并且需要一个有效的整数值。它将不接受None,并且在数据库中没有空值。有效值为 -2147483648 到 2147483647

age = models.IntegerField(null=True)

必填字段(表单验证)。如果该字段有None作为值,它将在数据库中转换为NULL

age = models.IntegerField(blank=True, null=True)

字段不是必需的(表单验证)。如果该字段传入None,则会被翻译成NULL

age = models.IntegerField(blank=True)

字段不是必需的(表单验证),但需要传入一个有效的整数值,因为数据库不接受空值。通常在这里你会用default=0给它一个默认值,或者在将值提交给orm之前完成一些验证。

【讨论】:

@Burhan Khalid - 很好的解释,我有一个字段mobile_no = models.BigIntegerField(max_length =10, blank=True, null=True)。当没有输入手机号码时,我尝试将None 传递给mobile_no 字段。我收到一个错误invalid literal for int() with base 10: 'None'。我哪里出错了? 您传递的是 string 'None'(注意引号)而不是值 None【参考方案2】:

尝试将None 传递给该字段而不是空字符串''

【讨论】:

【参考方案3】:

您可以在表单类中重写'clean'方法,然后清理整数数据以避免提交空字符串,请参见以下示例:

def clean(self):
    self.cleaned_data = super(YourForm, self).clean()
    if self.cleaned_data['age'] == '': self.cleaned_data['age'] = None
    return self.cleaned_data

【讨论】:

age = models.IntegerField(default=None) 这样的东西可以代替吗?

以上是关于如何将空值存储为整数字段的主要内容,如果未能解决你的问题,请参考以下文章

Flutter firebase setData()函数在完成异步函数之前将空值分配给字段

java 将空值注入自动装配字段(待验证)

access中查询出来值的为空,如何将空值改为0,具体表达式是啥,从啥地方输入表达式,多谢

sql 查询时有空值返回0怎么写

Hive/Bigsql Pandas 将浮点数转换为整数,使用 pyarrow 将空值转换为镶木地板文件

如何通过实体框架将空值传递给存储过程?