MySql数据库中创建一张test表,语句如下:
delimiter $$
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`a` varchar(45) NOT NULL,
`b` varchar(45) DEFAULT NULL,
`c` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8$$
字段a表示该字段不允许插入null值,但可以插入空字符串""。所以执行insert into test(a,b,c) values(null,null,null)将会报错。执行insert into test(a,b,c) values("",null,null),则可以正常插入一条记录到mysql数据库中。数据如图所示:。
因为b,c字段定义了default null,就是说插入一条记录时,如果b,c字段没有值,则数据会被设置为默认的null,如insert into test(a) values("");则数据库中的数据为id=7的记录:
如果b字段定义了默认值是''(注意是两个单引号,不是双引号),
delimiter $$
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`a` varchar(45) NOT NULL,
`b` varchar(45) NOT NULL DEFAULT '',
`c` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8$$
在执行insert into test(a) values("")时,b字段会默认插入空字符串。如下图id=9的记录:
总结:mysql中字段定义了not null,要么再设置default为空字符串或者其它不为NULL的值,要么必须在insert into 中显示插入不为NULL的值。
如果字段定义了可允许为空,则该字段如果没有显性在inser into语句中插入值,则使用数据库中定义的default值,可以为NULL。
下面讨论一下django模型与mysql的关系
mysql表依然如下:
delimiter $$
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`a` varchar(45) NOT NULL,
`b` varchar(45) DEFAULT NULL,
`c` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8$$
django中的模型如果定义为:
class Test(models.Model):
a = models.CharField(max_length = 45)
b = models.CharField(max_length = 45)
c = models.IntegerField(default = 0)
def __unicode__(self):
return self.id
class Meta:
db_table = u'test'
django的模型中每个字段都有null和blank两个属性,它们的含义如下:
null如果为 True , Django 在数据库中会将空值(empty)存储为 NULL 。默认为 False 。 blank如果为 True ,该字段允许不填(blank)。默认为 False 。 要注意,这与 null 不同。 null 纯粹是数据库范畴的,而 blank 是数据验证范畴的。如果一个字段的 blank=True,Django 的管理后台在做数据验证时,会允许该字段是空值。如果字段的 blank=False ,该字段就是必填的。 模型定义为上图所示,运行下面代码:t = model.Test()
t.save()
将会在数据库中生成记录如下:
如果将模型中的b字段null = True,代码如下:
class Test(models.Model):
a = models.CharField(max_length = 45)
b = models.CharField(max_length = 45,null = True)
c = models.IntegerField(default = 0)
def __unicode__(self):
return self.id
class Meta:
db_table = u'test'
再执行同样的代码:
t = model.Test()
t.save()
如果是数据库中的新记录的b字段为null,记录如下图:
在不使用form认证表单的情况下,对于模型中的b字段,blank无论设置为True或者False,执行下面代码:
t = model.Test()
t.save()
在数据库中的b字段都是空字符串。
对于模型中的a字段,因为在数据库中a字段设置了not null,如果模型中的a字段设置null = True:如下:
class Test(models.Model):
a = models.CharField(max_length = 45,null = True)
b = models.CharField(max_length = 45)
c = models.IntegerField(default = 0)
def __unicode__(self):
return self.id
class Meta:
db_table = u'test'
再执行:
t = model.Test()
t.save()
程序就会报错,如下图所示:
并且如果现在模型中a设置了null = True,已经和数据库中的设置冲突了,blank无论设置为True或者False,都仍会报上图的错误。
对于blank属性,可以这样认为,在不使用form和ModelForm的情况下,可以不用考虑该属性值对代码的影响。这个属性主要是在表单认证的时候表明该字段是不是require = True的。当blank = False时(默认为 False),在生成的表单中该字段require属性为True。反之为False。
下面我们定义一个ModelForm:
class TestForm(ModelForm):
class Meta:
model = model.Test
这里表单的字段控制由模型model.Test决定,从模型的定义中可以看出这些字段没有设置blank属性,也就是说这些字段默认属性为blank = False。对此如果request.POST中没有包含这三个字段的值,表单认证是无法通过的。
对于下面的代码:
a = model.Test.objects.get(id = 1)
form = forms.TestForm(request.POST,instance = a)
if form.is_valid():
form.save()
return rest.response("success")
else:
return rest.error_response(400, "fail")
先从数据库中获取一个对象a,然后用表单中的数据去更新a的字段值。如果有些字段值没有传值,但又默认通过的话,则使用模型中定义的模型值有覆盖原值。