How can I make all CharField in uppercase direct in model?
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.
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()
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)