class EmbeddedDocumentForm(
        with_metaclass(DocumentFormMetaclass, BaseDocumentForm)):
    def __init__(self,
                 parent_document,
                 data=None,
                 files=None,
                 position=None,
                 *args,
                 **kwargs):
        if self._meta.embedded_field is not None and \
                self._meta.embedded_field not in parent_document._fields:
            raise FieldError("Parent document must have field %s" %
                             self._meta.embedded_field)

        instance = kwargs.pop('instance', None)

        if isinstance(parent_document._fields.get(self._meta.embedded_field),
                      ListField):
            # if we received a list position of the instance and no instance
            # load the instance from the parent document and proceed as normal
            if instance is None and position is not None:
                instance = getattr(parent_document,
                                   self._meta.embedded_field)[position]

            # same as above only the other way around. Note: Mongoengine
            # defines equality as having the same data, so if you have 2
            # objects with the same data the first one will be edited. That
            # may or may not be the right one.
            if instance is not None and position is None:
                emb_list = getattr(parent_document, self._meta.embedded_field)
                position = next(
                    (i for i, obj in enumerate(emb_list) if obj == instance),
                    None)

        super(EmbeddedDocumentForm, self).__init__(data=data,
                                                   files=files,
                                                   instance=instance,
                                                   *args,
                                                   **kwargs)
        self.parent_document = parent_document
        self.position = position

    def save(self, commit=True):
        """If commit is True the embedded document is added to the parent
        document. Otherwise the parent_document is left untouched and the
        embedded is returned as usual.
        """
        if self.errors:
            raise ValueError("The %s could not be saved because the data"
                             "didn't validate." %
                             self.instance.__class__.__name__)

        if commit:
            field = self.parent_document._fields.get(self._meta.embedded_field)
            if isinstance(field, ListField) and self.position is None:
                # no position given, simply appending to ListField
                try:
                    self.parent_document.update(
                        **
                        {"push__" + self._meta.embedded_field: self.instance})
                except:
                    raise OperationError("The %s could not be appended." %
                                         self.instance.__class__.__name__)
            elif isinstance(field, ListField) and self.position is not None:
                # updating ListField at given position
                try:
                    self.parent_document.update(
                        **{
                            "__".join(("set", self._meta.embedded_field,
                                       str(self.position))):
                            self.instance
                        })
                except:
                    raise OperationError(
                        "The %s could not be updated at "
                        "position %d." %
                        (self.instance.__class__.__name__, self.position))
            else:
                # not a listfield on parent, treat as an embedded field
                setattr(self.parent_document, self._meta.embedded_field,
                        self.instance)
                self.parent_document.save()
        return self.instance
class DocumentForm(with_metaclass(DocumentFormMetaclass, BaseDocumentForm)):
    pass