首页 文章

在Django CharFields中自动截断max_length处的字段

提问于
浏览
27

我有一个 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 回答

  • -3

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

    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.py 文件中使用 models.CharField ,而只需使用TruncatingCharField .

    get_prep_value准备要插入数据库的字段的值,因此它是截断的理想位置 .

  • 36

    你为什么不使用TextField?从手册:

    对于大量文本,请使用TextField .

  • 4

    你为什么不用 ModelForm . ModelForm强制执行验证,将其默认的max_length设置为模型字段的max_length属性,并在调用 form.is_valid() 时引发正确的验证错误 . 这样,在表单验证之前,您不必保存表单 .

    或者,如果你想默默地传递验证和截断最适合你,写一个简单的django表单,并编写一个clean方法,将输入字符串截断为max_length并返回剥离的数据 . 在验证表单后从 form.cleaned_data 获取数据并保存对象 .

    所有考虑到这一事实,Forms都是为了在进入DB之前验证数据而设计的 .

  • 3

    这似乎不够优雅,必须有更好的方法 .

    截断行为首先发生的唯一原因是MySQL没有遵守SQL标准 . 在尝试将字符串插入到不足以容纳它的VARCHAR字段时,抛出异常是正确的响应 . MySQL会截断并插入 .

    如果你想静默地破坏你的数据,那么你必须以某种方式手动完成它 - PostgreSQL永远不会为你做这件事 .

相关问题