我有一个 max_length
集的字段 . 当我保存模型实例,并且字段的值大于 max_length
时,Django在数据库级别强制执行 max_length
. (参见关于模型的Django文档:http://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.CharField.max_length)
但是,由于我使用的是Postgres,我收到了一个 DatabaseError
异常,如下所示:
DatabaseError: value too long for type character varying(1000)
我宁愿自动截断该值(所以我没有例外) . 现在,我可以手动执行此操作,但我真正想要的是让我的所有模型自动截断该值 . (不一定是聪明的 . 只要在第999个角色切断它就可以了 . )
我应该只编写一个从models.Model导入的自定义类,并覆盖save()方法,循环遍历每个_meta.field,检查max_length,然后截断?这似乎不够优雅,必须有更好的方法 .
4 回答
您可以创建一个自动截断字段的自定义字段(我认为此代码应该可以工作,但请仔细检查它):
然后,不要在
models.py
文件中使用models.CharField
,而只需使用TruncatingCharField .get_prep_value准备要插入数据库的字段的值,因此它是截断的理想位置 .
你为什么不使用TextField?从手册:
你为什么不用
ModelForm
. ModelForm强制执行验证,将其默认的max_length设置为模型字段的max_length属性,并在调用form.is_valid()
时引发正确的验证错误 . 这样,在表单验证之前,您不必保存表单 .或者,如果你想默默地传递验证和截断最适合你,写一个简单的django表单,并编写一个clean方法,将输入字符串截断为max_length并返回剥离的数据 . 在验证表单后从
form.cleaned_data
获取数据并保存对象 .所有考虑到这一事实,Forms都是为了在进入DB之前验证数据而设计的 .
这似乎不够优雅,必须有更好的方法 .
截断行为首先发生的唯一原因是MySQL没有遵守SQL标准 . 在尝试将字符串插入到不足以容纳它的VARCHAR字段时,抛出异常是正确的响应 . MySQL会截断并插入 .
如果你想静默地破坏你的数据,那么你必须以某种方式手动完成它 - PostgreSQL永远不会为你做这件事 .