Automatic truncation of fields at max_length in Django CharFields

I have a field with the max_length set. When I save a model instance and the field value is greater than max_length , Django applies this max_length parameter at the database level. (See Django docs on models: http://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.CharField.max_length )

However, since I use Postgres, I get a DatabaseError exception similar to this:

 DatabaseError: value too long for type character varying(1000) 

I would rather instead automatically trim the value (so I have no exception). Now I can do it manually, but I would really like all my models to automatically truncate the value. (Not necessarily reasonable. Just cut it off on the 999th character in order.)

Should I just write a custom class that imports from models.Model and override the save () method, iterate through each _meta.field, check max_length and then truncate? It seems inelegant, and there should be a better way.

+20
django postgresql django-models
Aug 11 2018-10-10T00:
source share
4 answers

You can create a custom field that automatically crop the field (I think this code should work, but double check it):

 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 

Then, instead of using models.CharField in your models.py file models.py you simply use TruncatingCharField.

get_prep_value prepares the value for the field to be inserted into the database, so this is the perfect place to truncate.

+28
Aug 11 '10 at 17:07
source share

Why don't you use ModelForm . ModelForm applies validation by setting the default max_length value to simulate the field's max_length property and raising the correct validation error when calling form.is_valid() . This way you do not need to save the form until the form is validated.

Or, if you want you to silently skip the most suitable verification and truncation options for you, write a simple django form and write a clean method that truncates the input line to max_length and returns the split data. Take data from form.cleaned_data after validating the form and saving the object.

All given the fact, Forms are designed to validate data before going to DB.

+3
Aug 11 '10 at 15:23
source share

Why don't you use TextField? From the manual:

For large amounts of text, use TextField.

+2
Aug 11 '10 at 15:56
source share

It seems inelegant, and there should be a better way.

The only reason truncate behavior ever happens in the first place is because MySQL does not comply with the SQL standard. Throwing an exception is the correct answer when you try to insert a row into the VARCHAR field that is not wide enough to hold it. MySQL truncates and inserts instead.

If you want to spoil your data, then you have to do it manually - PostgreSQL will never do it for you.

-2
Aug 11 '10 at 18:37
source share



All Articles