开发者

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

开发者 https://www.devze.com 2023-03-28 05:45 出处:网络
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 CharField

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)


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/


Jazz's answer works like a charm for me.

I just want to point out that if you are using South migration tool, the schemamigration command will fail, unless you specify a introspect rule for the new custom field.

For "simple fields", you can simply add the following code to wherever your field is specified.

from south.modelsinspector import add_introspection_rules
add_introspection_rules([], ["^myapp\.stuff\.fields\.SomeNewField"])

Now the South migration should work.

FYI.

Reference: http://south.aeracode.org/wiki/MyFieldsDontWork

0

精彩评论

暂无评论...
验证码 换一张
取 消