Reputation: 1428
I'm trying out MongoEngine for a project and its quite good. I was wondering if it is possible to set a default value for a field from another field? Something like this
import mongoengine as me
class Company(me.Document):
short_name = me.StringField(required=True)
full_name = me.StringField(required=True, default=short_name)
this fails with an error ValidationError (Company:None) (StringField only accepts string values: ['full_name'])
:EDIT:
I did not mention that my app has a service layer which enabled me to simply do it like this:
if company_data['short_name'] is None:
myCompany.full_name = company_data['short_name']
obj = myCompany.save()
and it works quite nicely.
Upvotes: 6
Views: 7847
Reputation: 328
default
does not get passed the instance of the document, so you won't be able to achieve what you want.
The save
solution is ok, but the value of full_name
is not set until there is a save()
called.
Instead, use mongoengine's post_init
signal
@mongonegine.post_init.connect_via(Company)
def set_full_name(sender, document, **kwargs):
document.full_name = document.full_name or document.short_name
Company(short_name='hello').full_name' == 'hello'
Upvotes: 0
Reputation: 4685
Take a look at http://docs.mongoengine.org/guide/defining-documents.html#field-arguments:
You can achieve this by passing a function to default property of the field:
class ExampleFirst(Document):
# Default an empty list
values = ListField(IntField(), default=list)
class ExampleSecond(Document):
# Default a set of values
values = ListField(IntField(), default=lambda: [1,2,3])
class ExampleDangerous(Document):
# This can make an .append call to add values to the default (and all the following objects),
# instead to just an object
values = ListField(IntField(), default=[1,2,3])
Upvotes: 4
Reputation: 473993
You can override save()
method on a Document
:
class Company(me.Document):
short_name = me.StringField(required=True)
full_name = me.StringField()
def save(self, *args, **kwargs):
if not self.full_name:
self.full_name = self.short_name
return super(Company, self).save(*args, **kwargs)
Upvotes: 11