Using MongoEngine Document class methods for custom validation and pre-save hooks

mhermans picture mhermans · May 23, 2011 · Viewed 12.7k times · Source

I am currently exploring the possibilities of the MongoEngine "object document mapper". What is currently not clear to me is to what extent I can move my validation and object creation logic to the Document objects themselves.

I have the impression that it should not be a problem, but I'm not finding a lot of examples/caveats/best practices regarding issues as

  • Custom validation functions that are automatically called on save() to evaluate if field contents are valid;
  • Automatic generation of the identifier on save(), based on the hash of the contents of a field;

I think I need to override the save() method, so that I can call my custom logic, but the lack of examples leads me to believe that that may be a wrong approach...

Any examples, or references to high-quality codebases using mongoEngine, are welcome.

Answer

Prydie picture Prydie · Sep 13, 2013

Custom validation should now be done by implementing the clean() method on a model.

class Essay(Document):
    status = StringField(choices=('Published', 'Draft'), required=True)
    pub_date = DateTimeField()

    def clean(self):
        """
        Ensures that only published essays have a `pub_date` and
        automatically sets the pub_date if published and not set.
        """
        if self.status == 'Draft' and self.pub_date is not None:
            msg = 'Draft entries should not have a publication date.'
            raise ValidationError(msg)

        # Set the pub_date for published items if not set.
        if self.status == 'Published' and self.pub_date is None:
            self.pub_date = datetime.now()

Edit: That said, you have to be careful using clean() as it is called from validate() prior to validating the model based on the the rules set in your model definition.