@@ -832,7 +832,13 @@ def inlineformset_factory(document, form=DocumentForm,
832
832
class EmbeddedDocumentFormSet (BaseDocumentFormSet ):
833
833
def __init__ (self , data = None , files = None , save_as_new = False ,
834
834
prefix = None , queryset = [], parent_document = None , ** kwargs ):
835
- self .parent_document = parent_document
835
+ if parent_document is not None :
836
+ self .parent_document = parent_document
837
+
838
+ if 'instance' in kwargs :
839
+ instance = kwargs .pop ('instance' )
840
+ if parent_document is None :
841
+ self .parent_document = instance
836
842
837
843
queryset = getattr (self .parent_document ,
838
844
self .form ._meta .embedded_field )
@@ -848,7 +854,8 @@ def _construct_form(self, i, **kwargs):
848
854
# a huge amount of time iterating over the list field on form __init__
849
855
emb_list = getattr (self .parent_document ,
850
856
self .form ._meta .embedded_field )
851
- if emb_list is not None and len (emb_list ) < i :
857
+
858
+ if emb_list is not None and len (emb_list ) > i :
852
859
defaults ['position' ] = i
853
860
defaults .update (kwargs )
854
861
@@ -878,22 +885,15 @@ def save(self, commit=True):
878
885
objs = objs or []
879
886
880
887
if commit and self .parent_document is not None :
881
- # The thing about formsets is that the base use case is to edit
882
- # *all* of the associated objects on a model. As written, using
883
- # these FormSets this way will cause the existing embedded
884
- # documents to get saved along with a copy of themselves plus any
885
- # new ones you added.
886
- #
887
- # The only way you could do "updates" of existing embedded document
888
- # fields is if those embedded documents had ObjectIDs of their own,
889
- # which they don't by default in Mongoengine.
890
- #
891
- # In this case it makes the most sense to simply replace the
892
- # embedded field with the new values gathered form the formset,
893
- # rather than adding the new values to the existing values, because
894
- # the new values will almost always contain the old values (with
895
- # the default use case.)
896
- setattr (self .parent_document , self .form ._meta .embedded_field , objs )
888
+ field = self .parent_document ._fields .get (self .form ._meta .embedded_field , None )
889
+ if isinstance (field , EmbeddedDocumentField ):
890
+ try :
891
+ obj = objs [0 ]
892
+ except IndexError :
893
+ obj = None
894
+ setattr (self .parent_document , self .form ._meta .embedded_field , obj )
895
+ else :
896
+ setattr (self .parent_document , self .form ._meta .embedded_field , objs )
897
897
self .parent_document .save ()
898
898
899
899
return objs
0 commit comments