jvc26
jvc26

Reputation: 6513

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?

Upvotes: 5

Views: 3745

Answers (1)

DBrowne
DBrowne

Reputation: 723

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.

Upvotes: 10

Related Questions