19๐
You may wish to override to_python
, which will allow you to compare non-lowercase strings when doing database lookups. The actual method is get_prep_value
, but as that calls to_python
for CharField
, itโs more convenient to override that:
def to_python(self, value):
value = super(LowerCaseCharField, self).to_python(value)
if isinstance(value, basestring):
return value.lower()
return value
Now you can do queries like:
MyModel.objects.filter(lccf="MiXeD")
Edit:
Rereading your question, it looks like you want the lowering to take effect immediately. To do this, youโll need to create a descriptor (a new-style python object with __get__
and __set__
methods, see the python docs and the django code for related models) and override contribute_to_class
in the field to set the modelโs field to your descriptor.
Here is a full example off the top of my head, which should be reusable for all fields that want to modify the value on setting.
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))
2๐
Another way to do it would be to add a pre_save hook to your model, and then just convert all the fields you want to be lowercase to lowercase there using lower(). This is discussed here in a slightly different fashion. This way, any time the object is saved its field is converted to lower case.
Example:
@receiver(pre_save, sender=YourModel)
def convert_to_lowercase(sender, instance, *args, **kwargs):
instance.lowercase_field = instance.lowercase_field.lower()
- Django โ rendering many templates using templatetags is very slow
- Django and MPTT โ get only leaf nodes
- ImportError: cannot import name simplejson. I am using django v1.8 and django-Select2 v4.3.1
- Testing apps.py in django
1๐
Using Python properties is not straightforward because of the way django.models.Models magically set their instance attributes based on class attributes. There is an open bug out for this.
I ended up doing exactly what the original poster did.
It means you have to do:
>>> modelinstance.field_name="TEST"
>>> modelinstance.save() # Extra step
>>> print modelinstance.field_name
'test'
- How to create serializer for an enum field in django rest framework
- Using Django view variables inside templates
- Django sub-applications & module structure
- What does this operator means in django `reduce(operator.and_, query_list)`
- Django REST Framework nested resource key "id" unaccessible
- Django STATIC_URL is not working
- Django runserver custom database
- How to remove these '"' in django template