Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: Automatically setting empty strings in model fields to None?

I want to iterate over my model fields within a Django model and check if they are empty string and replace them with a null in the model save() method programmatically. This is because some CharFields need to be unique or have no value.

Example:

class Person(models.Model):
    name = models.CharField(blank=True, unique=True, null=True)
    nick_name = models.CharField(blank=True, unique=True, null=True)
    ...
    age = models.IntegerField()

    def save(self, *args, **kwargs):
        for field in self._meta.fields: # get the model fields
            if field=='':
                field = None
       super(Person, self).save(*args, **kwargs)

The above complains about a creation_counter which is unclear why an attempt to compare those values instead of the field value with the empty string is done.

This could be done manually, but I have too many models....

Any suggestions?

edit: Thanks to everyone who attempted to help me! :D

The solution that seems to work for me is posted by Jazz, but his code isn't showing up in his post. This is my version which is essentially identical, but with an extra check to make sure we are only overriding when necessary:

from django.db.models.Field import CharField as _CharField

class CharField(_CharField):
    def get_db_prep_value(self, value, *args, **kwargs):
        if self.blank == self.null == self.unique == True and value == '':
            value = None

        return super(CharField).get_db_prep_value(value, *args, **kwargs)
like image 880
GoogleDroid Avatar asked Dec 28 '22 15:12

GoogleDroid


1 Answers

In your case, I would suggest a custom model field, which subclasses a CharField and ensures that a empty string is converted to None -- overriding get_db_prep_value should do it.

class EmptyStringToNoneField(models.CharField):
    def get_prep_value(self, value):
        if value == '':
            return None  
        return value

class Person(models.Model):
    name = EmptyStringToNoneField(blank=True, unique=True, null=True)
    nick_name = EmptyStringToNoneField(blank=True, unique=True, null=True)

https://docs.djangoproject.com/en/dev/howto/custom-model-fields/

like image 136
jazz Avatar answered Jan 04 '23 12:01

jazz