Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does model.CharField('blank=False') work with save()?

I've a model like this with Django 1.1:

class Booking(models.Model):
  name = models.CharField(max_length=100)

By default, I'm reading that both 'null' and 'blank' are False.

So with a test like this...

class SimpleTest(TestCase):
    def test_booking_save(self):
        b = Booking()
        b.save()

... I expected the save to throw an exception. But it doesn't. It seems quite happy to create a new record with a blank name (Postgres and SQLite3).

I note that via the admin interface a save does indeed fail with a "this field is required".

Questions are:

  1. Is the 'blank' attribute only applied by forms?
  2. Is the fix to override the save() method and explicitly check that len(name) != 0?
  3. Have I misunderstood something which once understood resolves my misunderstanding?
like image 751
John Mee Avatar asked Sep 17 '09 01:09

John Mee


2 Answers

UPDATE: See the model validation documentation in recent Django versions.

Original answer: blank=True/False only applies to forms. Data validation currently only happens at the form level; this will change when the model-validation Google Summer of Code work gets merged in to trunk.

The only kind of validation that currently happens at the model layer is whatever errors your database backend will throw if it can't handle what it gets. In the case of an empty CharField you'll generally never get errors from the database, as Django sets the field to an empty string by default.

For now, you should use the save() method for any model-level validation you want. Soon (if you're on trunk) or when 1.2 comes out, use the model validation stuff.

like image 92
Carl Meyer Avatar answered Sep 17 '22 20:09

Carl Meyer


From the Django Docs:

"Note that empty string values will always get stored as empty strings, not as NULL. Only use null=True for non-string fields such as integers, booleans and dates."

Your code is storing an empty string.

To illustrate this, try:

class SimpleTest(TestCase):
    def test_booking_save(self):
        b = Booking()
        b.name = None
        b.save()
like image 43
Harold Avatar answered Sep 20 '22 20:09

Harold