Django CharFields中最大长度的自动截断字段

Django CharFields中最大长度的自动截断字段,django,postgresql,django-models,Django,Postgresql,Django Models,我有一个设置了max_length的字段。当我保存模型实例时,字段的值大于max\u length,Django会在数据库级别强制执行max\u length。(参见Django关于模型的文档:) 但是,由于我正在使用Postgres,我收到一个DatabaseError异常,如下所示: DatabaseError: value too long for type character varying(1000) 我宁愿自动截断该值(因此我没有异常)。现在,我可以手动执行此操作,但我真正想要的是

我有一个设置了
max_length
的字段。当我保存模型实例时,字段的值大于
max\u length
,Django会在数据库级别强制执行
max\u length
。(参见Django关于模型的文档:)

但是,由于我正在使用Postgres,我收到一个
DatabaseError
异常,如下所示:

DatabaseError: value too long for type character varying(1000)
我宁愿自动截断该值(因此我没有异常)。现在,我可以手动执行此操作,但我真正想要的是让我的所有模型自动截断值。(不一定是明智的。只需在第999个字符处将其截断即可。)


我是否应该编写一个自定义类,从models.Model导入并重写save()方法,循环遍历每个_meta.field,检查最大长度,然后截断?这似乎不雅观,一定有更好的方法。

为什么不使用
ModelForm
。ModelForm强制执行验证,将其默认最大长度设置为模型字段的最大长度属性,并在调用
form.is\u valid()
时引发正确的验证错误。这样,在验证表单之前,您不必保存表单

或者,如果您希望以静默方式传递验证并截断最适合您的字符串,请编写一个简单的django表单,然后编写一个干净的方法,将输入字符串截断为最大长度并返回剥离数据。从
表单获取数据。表单验证后清除数据并保存对象


考虑到这一事实,表单设计用于在进入数据库之前验证数据。

为什么不使用文本字段?从手册中:

对于大量文本,请使用 文本字段


您可以创建一个自动截断字段的自定义字段(我认为这段代码应该可以工作,但请仔细检查):

然后,不要在
models.py
文件中使用
models.CharField
,而是使用TruncatingCharField

为要插入到数据库中的字段准备值,因此它是截断的理想位置。

这似乎不雅观,必须有更好的方法

截断行为首先发生的唯一原因是MySQL未能遵守SQL标准。当试图将字符串插入到不够宽的VARCHAR字段中时,抛出异常是正确的响应。MySQL将截断并插入


如果你想悄悄地破坏你的数据,那么你必须以某种方式手动操作——PostgreSQL永远不会为你这么做。

是的,看看你写的,如果你想把它从第999个字符处截断,这对我来说,文本字段可能是一个更好的选择。回答不错,但可能还有另一个问题,这个问题是关于Django的,而不是关于PostgreSQL的。我喜欢PostgreSQL遵守标准并引发错误,但我(也喜欢OP)喜欢让Django知道截断(在尝试插入之前)是可以的。好吧,默认情况下这样做是不合适的。但是有一个选项可以自动完成这项工作是一个特性。工作起来很有魅力!放在哪里?glady已经使用了2年多,只有一件事需要强调:在使用
.create
(或导致create的变体,如
get\u或\u create
)之后,内存实例中的字段不会被截断。记住这一点很好
refresh\u from\u db
显示它被正确截断,但在创建对象后立即刷新对象并不太好。我无法从Field类本身找到任何方法来控制它,因此我最终添加了
Field。get\u prep\u value()
到带有TruncingCharField的模型的
save()
方法中。。。
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