Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need back reference from embedded document to parent #63

Closed
sergio-bershadsky opened this issue Aug 6, 2012 · 17 comments
Closed

Need back reference from embedded document to parent #63

sergio-bershadsky opened this issue Aug 6, 2012 · 17 comments
Milestone

Comments

@sergio-bershadsky
Copy link
Contributor

class Child(EmbeddedDocument):
    def save()
        pass #impossible

    def change_some_parents_attr_val()
        pass #impossible


class Parent(Document):
    child = EmbeddedDocumentField()

I think it's not so hard to create a back reference to a parent (root) document during class initialization

@rozza
Copy link
Contributor

rozza commented Aug 6, 2012

Can you please give an example of why you need to do this via the embedded document (bottom up) rather than from the document (top down) ?

@sergio-bershadsky
Copy link
Contributor Author

I've faced the shortage of this feature several times in my new project, a have a very dirty implemention for that case, but I think it is general problem, for example I add some data in child document, and I need to recalс cached data in parent document

class ListChild(EmbeddedDocument)
    pass

class Child(EmbeddedDocument):
    items = List(EmbeddedDocumentField(ListChild))

    def add(item):
       self.items.append(item)
       self.get_parent().total = len(self.items) #self.get_parent() returns a reference to Parent instance


class Parent(Document):
    child = EmbeddedDocumentField()
    total = IntegerField()

p = Parent.objects.first()
p.child.add(ListChild())
p.save()

#effected: p.child.items and p.quantity 

@sergio-bershadsky
Copy link
Contributor Author

What i'm doing for this case, it doesn't tested proper use it for your own risc. It surtanly doesn't works with Lists and Dicts in run time and with Dicts at init.

class MyEmbeddedDocument(EmbeddedDocument):

  _root_doc = None

  @property
  def root_doc(self):
    """
    returns the root document instance
    """
    return self._root_doc



class MyDocument(Document)
  def __init__(self, **kwargs):
    super(MDocument, self).__init__(**kwargs)

    #set back reference to main document (root document)
    self._messages = list()
    for embedded_doc in self.get_all_embedded_docs():
      embedded_doc._root_doc = self

  def __setattr__(self, key, value):
    """
    Connects root document in run time, doesn't work with iterables
    @example:
    doc = SomeDocument()
    doc.embedded_document = SomeEmbeddedDoceumnt()
    doc.embedded_document.root_doc == doc #True

    #or even
    doc = SomeDocument()
    doc.embedded_document.sub_embedded_document  = SomeEmbeddedDoceumnt()
    doc.embedded_document.sub_embedded_document.root_doc == doc #True
    """
    if issubclass(type(value), MyEmbeddedDocument):
      root_doc = getattr(value, 'root_doc', None)
      if root_doc is None and issubclass(type(self), MyDocument):
        value._root_doc = self
    object.__setattr__(self, key, value)

  def get_all_embedded_docs(self):
    """collects all embedded documents for the document"""
    embedded_docs = list()

    def check_field(value):
      if type(value) in (BaseList, list):
        check_list(value)
      if issubclass(type(value), MyEmbeddedDocument):
        embedded_docs.append(value)
        check_doc(value)

    def check_doc(doc):
      for name, value in doc._data.iteritems():
        check_field(value)

    def check_list(list):
      for value in list:
        check_field(value)

    check_doc(self)

    return embedded_docs

@rozza
Copy link
Contributor

rozza commented Nov 21, 2012

Added in 7d90aa7 - uses _instance

@rozza rozza closed this as completed Nov 21, 2012
@sergio-bershadsky
Copy link
Contributor Author

Wonderful!

@sergio-bershadsky
Copy link
Contributor Author

Seems to be deprecated, this ability disapeared in last commits

@cburmeister
Copy link

@rozza @nikitinsm any information on this??

@ochen
Copy link

ochen commented Apr 18, 2014

@rozza

any reason why this pointer is gone?

@lig lig reopened this Apr 18, 2014
@lig
Copy link
Contributor

lig commented Apr 18, 2014

regression?

@vartagg
Copy link

vartagg commented May 7, 2014

I didn't know about this feature. Is it really not working? mongoengine==0.8.7 all still working.

@lafrech
Copy link
Member

lafrech commented Feb 18, 2016

Fixed in #1131?

@touilleMan
Copy link
Member

@lafrech Maybe this old ticket hasn't been closed... Have you experieced the bug (given #1131 has been integrated in 0.10.1) ?

@lafrech
Copy link
Member

lafrech commented Feb 19, 2016

Hi @touilleMan.

Maybe this old ticket hasn't been closed...

Yes, pretty sure.

Have you experieced the bug (given #1131 has been integrated in 0.10.1) ?

No. I just found this page while searching for such a feature. Thanks to the link to #1131 I knew that the feature was supposed to be working correctly and I'm now using it.

My point was to ping the OP to let him close the bug. You should probably close it, since you have write access. He can reopen if issues arise.

More generally, there is currently 260 open bugs and I'm pretty sure a lot could be closed as fixed, obsolete, lacking info, or at least tagged as questions. IMHO, this would be better for the project both in terms of organization (identify actual issues) and image (a lot of open / unanswered bugs may let people think the project lacks maintenance; TBH I was a bit reluctant to use Mongoengine because or this). I offered to help cleaning flask-mongoengine bugtracker as a contribution to the project. I could give a hand on mongoengine as well. We may need to define a workflow (which labels to use, for instance), or maybe this has already been defined and it could be useful to add it to CONTRIBUTING.rst. If there is a better place to discuss this, please tell me.

@touilleMan
Copy link
Member

You're right about all those open issues.
Beside we're a small team (currently only @thedrow and me have the time to work on), so I think an offered hand is something really valuable for the sake of the project !

@thedrow what do you think about adding @lafrech to the project ?

PS: Nice to see another bordelais here ;-)

@thedrow
Copy link
Contributor

thedrow commented Feb 20, 2016

I'd be happy to welcome you on board.

@thedrow
Copy link
Contributor

thedrow commented Feb 20, 2016

@lafrech Done. Check your email.

@lafrech
Copy link
Member

lafrech commented Feb 22, 2016

Thanks. Invitation accepted. I can now close this bug myself as the issue should be fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants