Вы можете переопределить to_python
, что позволит вам сравнивать строки не в нижнем регистре при поиске в базе данных. Фактический метод - get_prep_value
, но так как он вызывает to_python
для CharField
, более удобно переопределить это:
def to_python(self, value):
value = super(LowerCaseCharField, self).to_python(value)
if isinstance(value, basestring):
return value.lower()
return value
Теперь вы можете делать запросы, такие как:
MyModel.objects.filter(lccf="MiXeD")
Редактировать:
Перечитывая ваш вопрос, похоже, вы хотите, чтобы понижение вступило в силу немедленно. Для этого вам нужно создать дескриптор (объект python нового стиля с методами __get__
и __set__
, см. документы по питону и код django для связанных моделей) и переопределить contribute_to_class
в поле, чтобы установить поле модели в ваш дескриптор.
Вот полный пример с моей головы, который должен быть многократно использован для всех полей, которые хотят изменить значение в настройке.
class ModifyingFieldDescriptor(object):
""" Modifies a field when set using the field's (overriden) .to_python() method. """
def __init__(self, field):
self.field = field
def __get__(self, instance, owner=None):
if instance is None:
raise AttributeError('Can only be accessed via an instance.')
return instance.__dict__[self.field.name]
def __set__(self, instance, value):
instance.__dict__[self.field.name] = self.field.to_python(value)
class LowerCaseCharField(CharField):
def to_python(self, value):
value = super(LowerCaseCharField, self).to_python(value)
if isinstance(value, basestring):
return value.lower()
return value
def contribute_to_class(self, cls, name):
super(LowerCaseCharField, self).contribute_to_class(cls, name)
setattr(cls, self.name, ModifyingFieldDescriptor(self))