Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix-#734: set attribute to None does not work (at least for fields with ... #767

Merged
merged 1 commit into from
Nov 10, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Changelog

Changes in 0.9.X - DEV
======================
- Set attribute to None does not work (at least for fields with default values) #734
- Querying by a field defined in a subclass raises InvalidQueryError #744
- Add Support For MongoDB 2.6.X's maxTimeMS #778
- abstract shouldn't be inherited in EmbeddedDocument # 789
Expand Down
16 changes: 11 additions & 5 deletions mongoengine/base/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class BaseField(object):
def __init__(self, db_field=None, name=None, required=False, default=None,
unique=False, unique_with=None, primary_key=False,
validation=None, choices=None, verbose_name=None,
help_text=None):
help_text=None, null=False):
"""
:param db_field: The database field to store this field in
(defaults to the name of the field)
Expand All @@ -60,6 +60,8 @@ def __init__(self, db_field=None, name=None, required=False, default=None,
model forms from the document model.
:param help_text: (optional) The help text for this field and is often
used when generating model forms from the document model.
:param null: (optional) Is the field value can be null. If no and there is a default value
then the default value is set
"""
self.db_field = (db_field or name) if not primary_key else '_id'

Expand All @@ -75,6 +77,7 @@ def __init__(self, db_field=None, name=None, required=False, default=None,
self.choices = choices
self.verbose_name = verbose_name
self.help_text = help_text
self.null = null

# Adjust the appropriate creation counter, and save our local copy.
if self.db_field == '_id':
Expand All @@ -100,10 +103,13 @@ def __set__(self, instance, value):

# If setting to None and theres a default
# Then set the value to the default value
if value is None and self.default is not None:
value = self.default
if callable(value):
value = value()
if value is None:
if self.null:
value = None
elif self.default is not None:
value = self.default
if callable(value):
value = value()

if instance._initialised:
try:
Expand Down
21 changes: 21 additions & 0 deletions tests/document/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -2706,5 +2706,26 @@ class Person(Document):
self.assertEquals(p4.height, 189)
self.assertEquals(Person.objects(height=189).count(), 1)

def test_null_field(self):
# 734
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)

# 735
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)

if __name__ == '__main__':
unittest.main()