[Fixed]-How can I make all CharField in uppercase direct in model?

16👍

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.

21👍

Here is how to override a Django Model Field and make it upper-case as of Django 1.8.

This will:

  • work by saving the upper-cased value to the database
  • returns an upper-cased value in the save response.

Here’s the code:

from django.db import models

class UpperCaseCharField(models.CharField):

    def __init__(self, *args, **kwargs):
        super(UpperCaseCharField, self).__init__(*args, **kwargs)

    def pre_save(self, model_instance, add):
        value = getattr(model_instance, self.attname, None)
        if value:
            value = value.upper()
            setattr(model_instance, self.attname, value)
            return value
        else:
            return super(UpperCaseCharField, self).pre_save(model_instance, add)

If you want to do this in Django rest framework, here’s the code:

from rest_framework import serializers

class UpperCaseSerializerField(serializers.CharField):

    def __init__(self, *args, **kwargs):
        super(UpperCaseSerializerField, self).__init__(*args, **kwargs)

    def to_representation(self, value):
        value = super(UpperCaseSerializerField, self).to_representation(value)
        if value:
            return value.upper()

8👍

Instead of defining a custom field, you can also use the RegexValidator:

from django.core.validators import RegexValidator

...

my_field = models.CharField(
    max_length=255,
    validators=[RegexValidator('^[A-Z_]*$',
                               'Only uppercase letters and underscores allowed.')],
)

(see Docs)

👤wfehr

2👍

django 4, just override the save() method of the model

from django.db import models

class MyModel(models.Model):
    my_field = models.CharField(max_length=255)
     
    def save(self, *args, **kwargs):
        self.my_field = self.my_field.upper()
        super().save(*args, **kwargs)

0👍

Here is my dirty and easier solution without having to deal with migrations:

    char_fields = [f.name for f in self._meta.fields if isinstance(f, models.CharField) and not getattr(f, 'choices')]
    for f in char_fields:
        val = getattr(self, f, False)
        if val:
            setattr(self, f, val.upper())
    super(Cliente, self).save(*args, **kwargs)

0👍

I copy @mariodev answer but it didn’t work in python3.
This is how a solved it:

from django.db import models

class UpperCharField(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

    def from_db_value(self, value, expression, connection, context=None):
        if self.is_uppercase:
            return value.upper()

        return value

Leave a comment