Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom field in Django get_prep_value() has no effect

So, I've made a similar class to this answer. It looks like:

class TruncatingCharField(models.CharField):
    description = _("String (truncated to %(max_length)s)")

    def get_prep_value(self, value):
        value = super(TruncatingCharField, self).get_prep_value(value)
        if value:
            value = value[:self.max_length]
        return value

I would expect that instantiating a model with this field with strings longer than the threshold should trigger truncation. However this appears not to be the case:

class NewTruncatedField(models.Model):
    trunc = TruncatingCharField(max_length=10)


class TestTruncation(TestCase):

    def test_accepted_length(self):
        trunc = 'a'*5
        obj = NewTruncatedField(trunc=trunc)
        self.assertEqual(len(obj.trunc), 5)

    def test_truncated_length(self):
        trunc = 'a'*15
        obj = NewTruncatedField(trunc=trunc)
        self.assertEqual(len(obj.trunc), 10)

The first test passes, as would be expected, but the second fails, as the field does not truncate its value. The get_prep_value() method is definitely being called (tested via breakpoints), and the output of value at the point of return is correctly truncated.

Why then is the value of the field in the obj object not truncated?

like image 887
jvc26 Avatar asked Mar 15 '23 14:03

jvc26


1 Answers

I believe get_prep_value() only effects what is saved to the DB, not the internal value of the Python object.

Try overriding to_python() and moving your logic there.

like image 145
DBrowne Avatar answered Mar 18 '23 03:03

DBrowne