mongoengine icon indicating copy to clipboard operation
mongoengine copied to clipboard

Documentation for `null` on a field

Open thanatos opened this issue 10 years ago • 6 comments

The docs presently read:

:param null: (optional) Is the field value can be null. If no and there is a default value then the default value is set

Aside from the obvious grammar errors, I still have no idea what it means, or what it does.

thanatos avatar Mar 16 '15 17:03 thanatos

Perhaps my coding skills are better than my english Here is part of the test I added with this feature:

    class User(Document):
        name = StringField()
        height = IntField(default=184, null=True)

    User.objects.delete()
    u = User(name='user')
    u.save()
    u_from_db = User.objects.get(name='user')
    u_from_db.height = None
    u_from_db.save()
    self.assertEquals(u_from_db.height, None)

    User.objects.delete()
    u = User(name='user')
    u.save()
    User.objects(name='user').update_one(set__height=None, upsert=True)
    u_from_db = User.objects.get(name='user')
    self.assertEquals(u_from_db.height, None)

Let me know if you still don't know what it means

DavidBord avatar Mar 17 '15 11:03 DavidBord

A PR with grammar error correction is welcome

DavidBord avatar Mar 22 '15 05:03 DavidBord

@DavidBord are you saying that following piece of code will solve my problem ?

User.objects(name='user').update_one(set__height=None, upsert=True) u_from_db = User.objects.get(name='user') self.assertEquals(u_from_db.height, None)

kartik115 avatar Aug 28 '18 10:08 kartik115

Digging into the code so far, I can only see null being used to ignore default.

e.g.

>>> from mongoengine import *
>>> class D(Document):
...  s1 = StringField(null=True, default='foo')
...  s2 = StringField(default='foo')
...  s3 = StringField()
...
>>> d = D()
>>> d.s1
>>> d.s1 = None
>>> d.s1
>>> d.s2
'foo'
>>> d.s2 = None
>>> d.s2
'foo'
>>> d.s3
>>> d.s3 = None
>>> d.s3

@DavidBord what is the use case for null=True? The behavior of StringField(null=True, default='foo') seems to be the same as StringField().

crunk1 avatar Sep 05 '18 02:09 crunk1

Originally, null=True meant:

Setting a field explicitly to None prevents the default setting from being used to set a default value.

The default setting is only actually used when saving. So, you wont see the effect of it until then.

So, using the example you had:

>>> d = D()
>>> d.s1 = None
>>> d.s2 = None
>>> d.save()
>>> x = D.objects(id=d.id).first()
>>> x.s1
>>> x.s2
'foo'
>>>

However, as of PR #1731 , it now also means:

If the field is explicitly set to None or is not set at all, then null is stored in the document when saved. Otherwise, the field is skipped on save.

This won't be visible from the python point of view. But the BSON document on MongoDB will set s1 to null if null=True is used. Otherwise, it doesn't include s1 at all in the underlying document.

If either of you feel up to it, it would be good to update the documentation. I've been swamped but keep meaning to do that.

JohnAD avatar Sep 06 '18 03:09 JohnAD

After reading this, it seems like the null-Parameter could be removed if Field(default=None) is changed to behave like Field(null=True). Maybe this behaviour is more intuitive.

der-joel avatar Sep 17 '21 11:09 der-joel