pythondjangodjango-modelsdjango-admindjango-custom-field

handling unique constraint for custom field in django admin


Hi I'm new to django and just took my first foray into using a custom field for my model. I have a Char field that I want to always be saved as lower case so I implemented it as a custom field as follows (learned from another Stack Overflow post):

from django.db import models
from django.db.models.fields import CharField

class LowercaseCharField(CharField):
    def pre_save(self, model_instance, add):
        current_value = getattr(model_instance, self.attname)
        setattr(model_instance, self.attname, current_value.lower())
        return getattr(model_instance, self.attname)


class Item(models.Model):
    name = LowercaseCharField(max_length=50, unique=True)

    def __str__(self):
        return self.name

I've tested this out in admin and indeed a field entry gets correctly converted to lowercase before it's saved. Unfortunately, when I tested the uniqueness constraint, admin isn't handling the Integrity Error gracefully. Instead of getting the clean error like I do if it's an exact case match from the get go:

enter image description here

I get the ugly error page:

enter image description here

How do I go about setting the custom field in such a way that the unique constraint is caught "early" enough to trigger the graceful error, or otherwise modify the admin so that this "later" error is handled more gracefully?

(Note: I am just using sqlite3 for my db at the moment)

UPDATE: In case any one is interested, here's the modified code that worked for me:

class LowercaseCharField(CharField):
    def get_db_prep_value(self, value, connection, prepared=False):
         return value.lower()

Solution

  • I don't think you'll make it by overriding pre_save, because pre_save gets called after uniqueness validation has occurred. Try with the other methods, such as get_db_prep_save or get_db_prep_value.