object created even if field was required

Multi tool use
object created even if field was required
#models.py
class Mymodel(models.Model):
name = models.CharField(max_length=100,null=False,blank=False)
email = models.EmailField(max_length=100,null=False,blank=False)
password = models.CharField(max_length=120,null=False,blank=False)
email_notification = models.BooleanField()
#views.py
obj=MyModel.objects.create(name="ok",password="dsfdsfdsfdsfsfds",email_notification=1)
even if email was required field,then also object was created when I see in the admin panel.What can be the issue,Why object got created,even if email field was mandatory?
Also if I go in admin panel and open that object and click save then it raises that email is required
django version is 2.0.4
– Nimish Bansal
Jul 3 at 7:37
email = models.EmailField(max_length=100,null=False,blank=False) it is not req.
– marin
Jul 3 at 7:41
@marin if this is not required why does it shows error on clicking save in django admin panel.Also, if email = models.EmailField(max_length=100) is required,then same situation arised
– Nimish Bansal
Jul 3 at 7:46
please, upload the full error message.
– Razia Khan
Jul 3 at 8:53
2 Answers
2
Note: You don't to have provide null=False,blank=False in your fields because those are the values used by default.(See the Django Field
__int__
signature.).
Field
__int__
def __init__(self, verbose_name=None, name=None, primary_key=False,
max_length=None, unique=False, blank=False, null=False,
db_index=False, rel=None, default=NOT_PROVIDED, editable=True,
serialize=True, unique_for_date=None, unique_for_month=None,
unique_for_year=None, choices=None, help_text='', db_column=None,
db_tablespace=None, auto_created=False, validators=(),
error_messages=None):
By default all the fields in database is created with NOT NULL
constraint. If you set null=True
for particular field, then django sets NULL
on the column in your DB. It’s the database equivalent of Python’s None
keyword.
NOT NULL
null=True
NULL
None
Example with null
argument
null
Assume that I have the following Mymodel
in my my_app
and I set email
field to null=True
.
Mymodel
my_app
email
null=True
class MyModel(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField(max_length=100, null=True)
password = models.CharField(max_length=120)
email_notification = models.BooleanField()
In Shell,
>> from my_app.models import MyModel
>> new = MyModel.objects.create(name="ok",
password="dsfdsfdsfdsfsfds",
email_notification=1)
>> new.email == None
>> True # As you can see Django sets db value
# as NULL and when we query the data it converts back to Python `None` object.
Example without null
argument
null
Assume that I have the following Mymodel
in my my_app
.(remember null
will be False
by default)
Mymodel
my_app
null
False
class MyModel(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField(max_length=100)
password = models.CharField(max_length=120)
email_notification = models.BooleanField()
In Shell,
>> from my_app.models import MyModel
>> new_obj = MyModel.objects.create(name="test",
password="test",
email_notification=1)
>> new_obj.email == ''
>> True
Ie,Django CharField
and TextField
the default values are stored in the DB as an empty string (''
). In other words if you create an object without providing values for a CharField
(or a TextField
) under the hood Django invokes the get_default
method and return ''
(only in this case). This value will be stored on the database.
CharField
TextField
''
CharField
TextField
get_default
''
The following is the source code of get_default
method.
get_default
def get_default(self):
"""Return the default value for this field."""
return self._get_default()
@cached_property
def _get_default(self):
if self.has_default():
if callable(self.default):
return self.default
return lambda: self.default
if not self.empty_strings_allowed or self.null and not connection.features.interprets_empty_strings_as_nulls:
return return_None
return str # return empty string
Lets answer the question,
Why object got created,even if email field was mandatory?
The answer is EmailField
is an instance of CharField
Hence default value ''
will be used while creating an object in database. That is why you are not getting django.db.utils.IntegrityError
.
EmailField
CharField
''
django.db.utils.IntegrityError
>> new_obj = Mymodel.objects.create(name='tes1t', password='test1', email_notification=1)
>>> new_obj.email
''
Also if I go in admin panel and open that object and click save then
it raises that email is required
Remember blank
is different than null
. null
is purely database-related, whereas blank
is validation-related. So when you create an object directly in Python code, or execute raw SQL yourself, you are actually bypassing all of Django’s input validation. But in admin, Django is validating the input through the model form. Since in your case blank
is set to False(blank not allowed), model form will raise Email is required
Error.
blank
null
null
blank
blank
Email is required
Here is the relevant Django documentation for blank
argument.
blank
Field.blank
If True, the field is allowed to be blank. Default is False. Note
that this is different than null. null is purely database-related,
whereas blank is validation-related. If a field has blank=True, form
validation will allow entry of an empty value. If a field has
blank=False, the field will be required.
Additional resources
Thanks alot :-)
– Nimish Bansal
Jul 5 at 16:44
@Nimish Bansal: You are always welcome. :)
– a_python_user
Jul 5 at 16:52
I explained the same thing in more easy way than a higher level overview :).
– pujanm
Jul 6 at 8:20
There is no issue with django you will have to create proper Django Model Form validation so that the empty string isn't ignored and it will raise an error for the blank field.
Ya I have did that only, but why then the same object cannot be created via admin panel,if it can be done by the commands
– Nimish Bansal
Jul 3 at 14:54
Actually, admin panel is also built on top of Django Forms and they have used some form validation to check whether a required field is empty or not. You can perform the same validation by m.save(commit=False) which will not save the object actually and then you can perform a check whether the field is empty or not and raise exceptions accordingly.
– pujanm
Jul 3 at 15:19
so does that mean without form validation it will not stop creation of object as per the models constraints.validation will be necessary?
– Nimish Bansal
Jul 3 at 17:20
Yes, it is necessary. I also was stuck like you on one project back but later on I realized that we have to validate on our own and throw exceptions accordingly.
– pujanm
Jul 3 at 17:23
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
django version ??
– Robert
Jul 3 at 7:34