(Django) Trim whitespaces from charField

zardon picture zardon · Feb 18, 2011 · Viewed 32.4k times · Source

How do I strip whitespaces (trim) from the end of a charField in Django?

Here is my Model, as you can see I've tried putting in clean methods but these never get run.

I've also tried doing name.strip(), models.charField().strip() but these do not work either.

Is there a way to force the charField to trim automatically for me?

Thanks.

from django.db import models
from django.forms import ModelForm
from django.core.exceptions import ValidationError
import datetime

class Employee(models.Model):
    """(Workers, Staff, etc)"""
    name                = models.CharField(blank=True, null=True, max_length=100)

    def save(self, *args, **kwargs):
        try:
            # This line doesn't do anything??
            #self.full_clean()
            Employee.clean(self)
        except ValidationError, e:
            print e.message_dict

        super(Employee, self).save(*args, **kwargs) # Real save

    # If I uncomment this, I get an TypeError: unsubscriptable object
    #def clean(self):
    #   return self.clean['name'].strip()

    def __unicode__(self):
        return self.name

    class Meta:
        verbose_name_plural = 'Employees'

    class Admin:pass


class EmployeeForm(ModelForm):
    class Meta:
        model = Employee

    # I have no idea if this method is being called or not  
    def full_clean(self):       
        return super(Employee), self.clean().strip()
        #return self.clean['name'].strip()

Edited: Updated code to my latest version. I am not sure what I am doing wrong as it's still not stripping the whitespace (trimming) the name field.

Answer

Jeremy Lewis picture Jeremy Lewis · Jun 14, 2011

When you're using a ModelForm instance to create/edit a model, the model's clean() method is guaranteed to be called. So, if you want to strip whitespace from a field, you just add a clean() method to your model (no need to edit the ModelForm class):

class Employee(models.Model):
    """(Workers, Staff, etc)"""
    name = models.CharField(blank=True, null=True, max_length=100)

    def clean(self):
        if self.name:
            self.name = self.name.strip()

I find the following code snippet useful- it trims the whitespace for all of the model's fields which subclass either CharField or TextField (so this also catches URLField fields) without needing to specify the fields individually:

def clean(self):
    for field in self._meta.fields:
        if isinstance(field, (models.CharField, models.TextField)):
            value = getattr(self, field.name)
            if value:
                setattr(self, field.name, value.strip())

Someone correctly pointed out that you should not be using null=True in the name declaration. Best practice is to avoid null=True for string fields, in which case the above simplifies to:

def clean(self):
    for field in self._meta.fields:
        if isinstance(field, (models.CharField, models.TextField)):
            setattr(self, field.name, getattr(self, field.name).strip())