1

I have a postgres Database and a model with a field as blank=False and null=True. Let's say:

class MyModel(models.Model):
    param1 = models.CharField(max_length=1024)
    param2 = models.CharField(max_length=1024)
    info = models.CharField(max_length=1024, blank=False, null=False) 

Now, when I am creating a model like this:

m = MyModel(param1=val1, param2=val2)

it basically won't raise any exception for info field on saving. Even more, it will keep an empty value for info in the database after using save method.

UPDATED
When instantiating the model like this:
m = MyModel(param1=val1, param2=val2, info=None)
saving will raise an exception in that case

Any suggestions why does it happen? In my opinion if I miss to add a value in the model initialization, it should be at least assumed as None, but it's not. I googled that and couldn't find an specific answer for that. But, found that only full_clean() model method performs checking and raises exceptions like these:

ValidationError: {'info': ['This field cannot be blank.'], 'owner': ['This field cannot be blank.']}

Any help is welcome!

djvg
  • 11,722
  • 5
  • 72
  • 103
Iulian Pinzaru
  • 400
  • 3
  • 10
  • Did you remember to run migrations after you made that change – Damilola Oct 16 '18 at 22:03
  • Damilola, yes I did... but unfortunately it allows me to initialize the Instance while skipping to refer other params. As I have mentioned, you could write like: ```MyModel(param1=val1, param2=val2, info=None)``` and in this case it will raise the exception. But if I just remove info=None, it won't. That's what I can't understand. I was thinking that Django should assume that missing any argument to the constructor will be interpreted at least as None. Am I clear? – Iulian Pinzaru Oct 19 '18 at 16:56

2 Answers2

1

So after researching I came up with this answer:
First of all, blank stands only for form validation, and null for DB validation (docs). As well, Django always assume the empty value for a missing parameter, but with a little bit different behavior for those field types.

The key difference is that for:

  • Char fields - it uses an empty string (which is ''), the default Django implementation. So if Django sees that there is a missing parameter, it won't pass None for that type of field, since NULL are not being recommended to be stored in DB for char fields. ( details here )

  • Other fields - it uses an empty value (which is None). So Django sees that there is a missing parameter, it will assume it's None. But since the database restriction null=False, it will raise the exception.

So the conclusion is that only non-charfields that are being supposed to use database constraint null=False - are being checked on save method for missing params by raising exceptions.

Now if you wanna raise exceptions for Charfields as well, you need to use full_clean (used by forms) that will tell you what type of field can't be blank (or missing). So in the end, the right way is to use blank=False and then full_clean to detect missing Charfields. Or/And, you can override the model`s clean() method if have some additional logic to those fields.

djvg
  • 11,722
  • 5
  • 72
  • 103
Iulian Pinzaru
  • 400
  • 3
  • 10
  • 1
    Another way to force the `IntegrityError` to be raised upon saving/creating objects, is by explicitly setting `default=None` on the `CharField`, *in addition to* `null=False` and `blank=False`. – djvg Jan 14 '19 at 10:49
-1
info = models.CharField('Facts and features', max_length=1024)
aman kumar
  • 3,086
  • 1
  • 17
  • 24
  • 2
    Could you please be more explicit in your explanation? As far as I know, django model has by default blank=False and null=False. So what's that ? – Iulian Pinzaru Oct 16 '18 at 19:04