Geo
Geo

Reputation: 96947

How can I impose these constraints on my model using django?

This is my model:

class MyModel(models.Model):
  s1 = models.CharField(max_length=255)
  s2 = models.CharField(max_length=255)

I was expecting django not to allow me to have empty strings considered as valid, as I read in the documentation that both blank and null are by default false. Example:

python manage.py shell

>>> a = MyModel()
>>> a.s1
''
>>> a.save()
>>> a.id()
1

Why didn't it raise an exception that the string was blank? Also, is there no such thing as a min_length? I want to limit my fields to at least 3 chars.

Upvotes: 2

Views: 454

Answers (1)

Shawn Chin
Shawn Chin

Reputation: 86944

blank is a validation-related attribute, which means it will only apply when data is entered via the django-admin site or a form derived from the model using ModelForm.

Example:

class MyForm(forms.ModelForm):
    class Meta:
        model = MyModel

>>> f = MyForm({"s1":""})
>>> f.is_valid()
False
>>> f = MyForm({"s1":"hello world"})
>>> f.is_valid()
True
>>> a = f.save()
>>> a
<MyModel: MyModel object>
>>> a.id
10

min_length

min_length does exists, but as an argument for forms.CharField not models.CharField.

class MyForm(forms.ModelForm):
    class Meta:
        model = MyModel
    s1 = forms.CharField(min_length=3, max_length=100)


>>> f = MyForm({"s1":"12"})
>>> f.is_valid()
False
>>> f = MyForm({"s1":"1234"})
>>> f.is_valid()
True

Raising exceptions on unspecified char fields (without forms)

By setting default=None, the charfield will default to NULL instead of "" which will raise an exception when the model is saved manually (unless null=True is specified).

class MyModel(models.Model):
  s1 = models.CharField(max_length=255, default=None)


>>> m = MyModel()
>>> m.save()
Traceback (most recent call last):
  File "<console>", line 1, in ?
  <.... trimmed for brevity ...>
  File "/usr/lib/python2.3/site-packages/django/db/backends/sqlite3/base.py", line 193, in execute
    return Database.Cursor.execute(self, query, params)
IntegrityError: test_mymodel.s1 may not be NULL

I've only tested this on an old-ish version of django so YMMV

Update

From 1.2 onwards, django models come with validation built-in which means you can trigger the validation functions by calling Model.full_clean(), without having to use ModelForm.

class MyModel(models.Model):
    s1 = models.CharField(max_length=100)

    def save(self, *args, **kwargs):
        self.full_clean()
        Super(MyModel, self).save(*args, **kwargs)


>>> m = MyModel()
>>> m.save()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/tmp/lsc/playground/zoo/models.py", line 42, in save
    self.full_clean()
  File "/usr/lib/pymodules/python2.6/django/db/models/base.py", line 881, in full_clean
    raise ValidationError(errors)
ValidationError: {'s1': [u'This field cannot be blank.']}

Upvotes: 2

Related Questions