Search code examples
djangomodels

How can I make all CharField in uppercase direct in model?


I tried to use UpperCase in all my CharField, in all my Django Model.

Today I have some code in my save method:

def save(self, *args, **kwargs):
        for field_name in ['razao_social', 'nome_fantasia', 'cidade', 'endereco','bairro', 'uf', 'cli_parc_nomeparc', 'cli_repr_nomerepr']:
            val = getattr(self, field_name, False)
            if val:
                setattr(self, field_name, val.upper())
        super(Pessoa, self).save(*args, **kwargs)

But its take some time. There`s any method to put some uppercase=True in my models?

Thanks.


Solution

  • The correct way would be to define custom model field:

    from django.db import models
    from django.utils.six import with_metaclass
    
    
    class UpperCharField(with_metaclass(models.SubfieldBase, models.CharField)):
        def __init__(self, *args, **kwargs):
            self.is_uppercase = kwargs.pop('uppercase', False)
            super(UpperCharField, self).__init__(*args, **kwargs)
    
        def get_prep_value(self, value):
            value = super(UpperCharField, self).get_prep_value(value)
            if self.is_uppercase:
                return value.upper()
    
            return value
    

    and use it like so:

    class MyModel(models.Model):
        razao_social = UpperCharField(max_length=50, uppercase=True)
        # next field will not be upper-cased by default (it's the same as CharField)
        nome_fantasia = UpperCharField(max_length=50)
        # etc..
    

    you also need to resolve south migration issues (if necessary), by adding this code:

    from south.modelsinspector import add_introspection_rules
    add_introspection_rules([
        (
            [UpperCharField],
            [],
            {
                "uppercase": ["uppercase", {"default": False}],
            },
        ),
    ], ["^myapp\.models\.UpperCharField"])
    

    (path in the last line depends on the field class localization. Please read the south docs for explanation.)

    Although there's a small downside when you use shell for instance to create model object and save it in variable:

    my_object = MyModel.objects.create(razao_social='blah')
    print my_object.razao_social
    

    you won't get upper-cased value. You need to retrieve the object from the database. I will update this post, when I find out how to resolve this issue as well.