Django 1.11迁移时DateTimeField验证错误求助
解决Django 1.11 DateTimeField迁移验证错误的问题
我来帮你搞定这个升级时遇到的datetime字段问题!
问题出在哪?
在Django 1.8里,你给DateTimeField设了default=''——其实这是个不规范的用法,DateTimeField根本不接受空字符串当默认值。只不过当时Django的验证比较宽松,没揪出来这个问题。升级到1.11后,框架对字段类型的校验严格了很多,空字符串没法被解析成合法的datetime格式,所以迁移或者读取数据时就炸出了那个验证错误。
一步步解决
1. 先把模型字段定义捋顺
你现在把default改成None是完全正确的,就保持这个设置就行:
timeToServe = models.DateTimeField( null=True, blank=True, default=None, auto_now=False, auto_now_add=False, verbose_name=get_lang(None, 'time_to_serve') )
这里几个参数的作用:
null=True:允许数据库里这个字段存NULL值blank=True:表单提交时可以不填这个字段default=None:新建对象时如果不指定该字段,默认存NULL
2. 清理数据库里的旧数据坑
如果你的数据库里已经有timeToServe字段是空字符串的记录,这些旧数据会继续触发错误,得先把它们改成NULL。有两种简单方法:
方法一:用Django Shell处理
打开终端跑这个命令进shell:
python manage.py shell
然后执行更新(把myapp换成你的应用名,Booking换成你的模型名):
from myapp.models import Booking Booking.objects.filter(timeToServe='').update(timeToServe=None)
方法二:直接跑SQL语句
根据你用的数据库类型执行对应的SQL:
- MySQL:
UPDATE myapp_booking SET timeToServe = NULL WHERE timeToServe = ''; - PostgreSQL:
UPDATE myapp_booking SET "timeToServe" = NULL WHERE "timeToServe" = '';
3. 调整迁移文件(如果需要)
看你现在的迁移文件0021_auto_xxxx.py,AlterField里的default已经是None了,这没问题。但如果执行迁移还是报错,可以试试回滚后重新生成:
- 先回滚到上一个正常的迁移版本:
python manage.py migrate myapp 0020_之前的迁移文件名 - 重新生成迁移:
python manage.py makemigrations myapp - 再执行迁移:
python manage.py migrate myapp
4. 验证效果
搞定上面的步骤后,试试新建一个对象不设timeToServe:
from myapp.models import Booking # 这里填你模型的其他必填字段 new_booking = Booking.objects.create(name="测试订单", ...) print(new_booking.timeToServe) # 应该输出None,而且不会有验证错误
这样就能实现你要的“创建对象时无需设置datetime字段”的需求,同时解决迁移时的验证错误啦~
内容的提问来源于stack exchange,提问作者Jon
相关产品推荐
相关产品推荐

