mhermans mhermans - 3 months ago 76
Python Question

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

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

You can override save(), with the usual caveat that you must call the parent class's method.

If you find that you want to add validation hooks to all your models, you might consider creating a custom child class of Document something like:

class MyDocument(mongoengine.Document):

    def save(self, *args, **kwargs):
        for hook in self._pre_save_hooks:
            # the callable can raise an exception if
            # it determines that it is inappropriate
            # to save this instance; or it can modify
            # the instance before it is saved
            hook(self):

        super(MyDocument, self).save(*args, **kwargs)

You can then define hooks for a given model class in a fairly natural way:

class SomeModel(MyDocument):
    # fields...

    _pre_save_hooks = [
        some_callable,
        another_callable
    ]