Reputation: 195
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)
Upvotes: 4
Views: 6491
Reputation: 68
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
Upvotes: 0
Reputation: 2379
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/
Upvotes: 11