44

I have a simple model which looks like this:

class Group(models.Model):
    name = models.CharField(max_length = 100, blank=False)

I would expect this to throw an integrity error, but it does not:

group = Group() # name is an empty string here
group.save()

How can I make sure that the name variable is set to something non-empty? I.e to make the database reject any attempts to save an empty string?

Kristian
  • 6,357
  • 4
  • 36
  • 37

5 Answers5

30

another option that doesn't require you to manually call clean is to use this:

name = models.CharField(max_length=100, blank=False, default=None)
  • blank will prevent an empty string to be provided in the admin or using a form or serializer (most cases). However as pointed out in the comments, this unfortunately does not prevent things like model.name = "" (manually setting blank string)
  • default=None will set name to None when using something like group = Group(), thus raising an exception when calling save
rptmat57
  • 3,643
  • 1
  • 27
  • 38
  • 2
    "blank will prevent an empty string to be provided in your model". This is false. It only prevents empty strings to be passed in the admin or anywhere a proper form or serializer is used. It doesn't prevent `Model.objects.create(name="")` or `model.name = ""; model.save()`. – Gabriel Jun 02 '21 at 06:21
  • you are absolutely right. I'll update my answer – rptmat57 Jun 28 '21 at 16:05
  • And how would be the best way to not pass any empty string? – Elias Prado Dec 22 '21 at 22:17
  • 1
    blank is by default set to False. No need to set it again..won't even reflect in the migration..https://docs.djangoproject.com/en/4.0/ref/models/fields/ – Geofrey Asiimwe Mar 11 '22 at 06:43
  • sure, but in cases like this, I prefer to set it explicitly, because it is very intentional `blank=False, default=None` go together in my mind. personal preference – rptmat57 Mar 12 '22 at 15:33
21

From the Django docs in this case, your name will be stored as an empty string, because the null field option is False by default. if you want to define a custom default value, use the default field option.

name = models.CharField(max_length=100, blank=False, default='somevalue')

On this page, you can see that the blank is not database-related.

Update:

You should override the clean function of your model, to have custom validation, so your model def will be:

class Group(models.Model):
  name = models.CharField(max_length=100, blank=False)
  def clean(self):
    from django.core.exceptions import ValidationError
    if self.name == '':
        raise ValidationError('Empty error message')

Or you can replace ValidationError to something else. Then before you call group.save() call group.full_clean() which will call clean()

Other validation related things are here.

senshin
  • 10,022
  • 7
  • 46
  • 59
balazs
  • 5,698
  • 7
  • 37
  • 45
  • 1
    I see what you mean. What I would really like is to reject any non-empty strings.. – Kristian Aug 04 '11 at 12:41
  • I see, so you want to validate the model. Than I think you should use group.[full_clean()](https://docs.djangoproject.com/en/dev/ref/models/instances/#id1) before `group.save()`. But I've never used it. :) – balazs Aug 04 '11 at 13:08
  • 10
    One way to avoid needing to ensure `full_clean()` is called is to use the `Charfield(default=None)`. This will raise `IntegrityError` instead of `ValidationError` – DanH Apr 14 '15 at 12:28
  • @DanH DanH's comment should be the true answer to this question. thank you. – matias elgart May 19 '18 at 11:54
10

Or you can simply use MinLengthValidator with a 1-char minimum:

from django.core.validators import MinLengthValidator

class Company(BaseModel):
    """Company"""

    name = models.CharField(max_length=255,
                            validators=[MinLengthValidator(1)])
Dave Schweisguth
  • 36,475
  • 10
  • 98
  • 121
Ricardo
  • 618
  • 9
  • 11
  • Thanks for your elegant solution, it helped me a lot! – Dmitry Fedotkin Dec 02 '16 at 07:31
  • Could you use `validators=[bool]`? `bool(value)` would return false for anything falsey, so empty string, None, etc. Although wouldn't work if zero numeric, empty list, etc. are valid. – Chris Apr 04 '19 at 16:22
  • 7
    This will not work when you save a model using instance.save() or model.create(). Only works when using ModelForm. Check https://docs.djangoproject.com/en/dev/ref/validators/#how-validators-are-run – NFern May 09 '19 at 03:59
8

I spent a long time looking for the best solution for this simple (and old) problem, And as of Django 2.2, there is actually a really simple answer, so I'll write it here in case someone still encounters the same problem:

Since Django 2.2, we can define CheckConstraints, so it's easy to define a non-empty string constraint:

from django.db import models

class Article(models.Model):
   title = models.CharField(max_length=32)

    class Meta:
        constraints = [
            models.CheckConstraint(check=~models.Q(title=""), name="non_empty_title")
        ]
Lotram
  • 729
  • 6
  • 17
1

Django’s validation system assumes that all fields are required,unless you mention that its ok to leave it blank..

Have you registered the class in Admin ? does it show errors when you leave it blank ??

Django krishna

Vamsi Krishna B
  • 11,377
  • 15
  • 68
  • 94
  • 9
    I am not using the Admin interface, but it looks like blank=True only has effect there. I would like the system to reject blank fields from anywhere.. – Kristian Aug 04 '11 at 12:43