我的字段设置为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,然后截断?这似乎不够优雅,必须有更好的方法。
答案 0 :(得分:37)
你可以创建一个自动截断字段的自定义字段(我认为这段代码应该有效,但仔细检查一下):
class TruncatingCharField(models.CharField):
def get_prep_value(self, value):
value = super(TruncatingCharField,self).get_prep_value(value)
if value:
return value[:self.max_length]
return value
然后,您不必在models.CharField
文件中使用models.py
,而只需使用TruncatingCharField。
get_prep_value
准备要插入数据库的字段的值,因此它是截断的理想位置。
答案 1 :(得分:5)
为什么不使用TextField?从手册:
对于大量文字,请使用 TextField更新。
答案 2 :(得分:3)
为什么不使用ModelForm
。 ModelForm强制执行验证,将其默认max_length设置为模型字段的max_length属性,并在调用form.is_valid()
时引发正确的验证错误。这样您就不必保存表单,直到表单被验证为止。
或者,如果你想默默地传递验证和截断最适合你,写一个简单的django表单,并编写一个clean方法,将输入字符串截断为max_length并返回剥离的数据。在验证表单后从form.cleaned_data
获取数据并保存对象。
所有考虑到这一事实,Forms都是为了在进入DB之前验证数据而设计的。
答案 3 :(得分:-3)
这似乎不够优雅,必须有更好的方法。
首先发生截断行为的唯一原因是MySQL无法遵守SQL标准。在尝试将字符串插入到不足以容纳它的VARCHAR字段时,抛出异常是正确的响应。 MySQL会截断并插入。
如果你想要无声地破坏你的数据,那么你必须以某种方式手动完成它 - PostgreSQL永远不会为你做这件事。