Использование методов класса MongoEngine Document для пользовательской проверки и предварительного сохранения хуков - PullRequest
14 голосов
/ 23 мая 2011

В настоящее время я изучаю возможности MongoEngine «объектный картограф». В настоящее время мне неясно, в какой степени я могу переместить свою логику проверки и создания объектов в сами объекты Document.

У меня сложилось впечатление, что это не должно быть проблемой, но я не нахожу много примеров / предостережений / лучших практик в отношении проблем как

  • Пользовательские функции проверки, которые автоматически вызываются при сохранении () для оценки допустимости содержимого поля;
  • Автоматическая генерация идентификатора при сохранении () на основе хеша содержимого поля;

Я думаю, что мне нужно переопределить метод save (), чтобы я мог вызывать свою собственную логику, но отсутствие примеров приводит меня к мысли, что это может быть неправильный подход ...

Приветствуются любые примеры или ссылки на высококачественные кодовые базы, использующие mongoEngine.

Ответы [ 3 ]

22 голосов
/ 13 сентября 2013

Настраиваемая проверка теперь должна выполняться с помощью реализации метода clean() в модели .

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()

Редактировать: Тем не менее, вы должны бытьосторожно используйте clean() как он вызывается из validate() перед проверкой модели на основе правил, установленных в определении вашей модели.

14 голосов
/ 07 июля 2011

Вы можете переопределить save() обычным предупреждением, которое вы должны вызывать методом родительского класса.

Если вы обнаружите, что хотите добавить проверочные хуки ко всем своим моделям, вы можете рассмотреть возможность созданиядочерний класс Document что-то вроде:

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)

Затем вы можете определить хуки для данного модельного класса довольно естественным образом:

class SomeModel(MyDocument):
    # fields...

    _pre_save_hooks = [
        some_callable,
        another_callable
    ]
7 голосов
/ 23 августа 2012

Вы также можете переопределить метод проверки в Document, но вам нужно будет проглотить ошибки Document суперкласса, чтобы вы могли добавить к ним свои ошибки

К сожалению, это зависит от внутренних деталей реализации в MongoEngine, поэтомукто знает, сломается ли он в будущем.

class MyDoc(Document):
    def validate(self):
        errors = {}
        try:
            super(MyDoc, self).validate()
        except ValidationError as e:
            errors = e.errors

        # Your custom validation here...
        # Unfortunately this might swallow any other errors on 'myfield'
        if self.something_is_wrong():
            errors['myfield'] = ValidationError("this field is wrong!", field_name='myfield')

        if errors:
            raise ValidationError('ValidationError', errors=errors)

Кроме того, в MongoEngine теперь есть надлежащая поддержка сигналов для обработки других видов хуков (таких как генерация идентификатора, которую вы упомянули в вопросе).

http://mongoengine.readthedocs.io/en/latest/guide/signals.html

...