mongoengine
mongoengine copied to clipboard
Documentation for `null` on a field
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.
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
A PR with grammar error correction is welcome
@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)
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().
Originally, null=True meant:
Setting a field explicitly to None prevents the
defaultsetting 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
nullis 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.
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.