-1

I am developing a project with flask and mongodb(mongoengine drive). The application uses Note model as a embeddedDocument for User Modal.

class User(db.Document, UserMixin):
    fields like created_at, content, slug etc...
    notes = db.ListField(db.EmbeddedDocumentField('Note'))

class Note(db.Document):
     fields like created_at, content, slug, URLLink, isSecret etc...
     content = db.StringField(required=True)
     tags = db.ListField(db.StringField(required=True, max_length=20)

When I try to Update a Note it's okay, but then trying to append the updated note in the User collection I stucked!

views.py

@app.route("/update_quote/<string:id>" ,methods=['POST'])
@login_required
def update_quote(id):
    note = Note.objects(id=id).first()

    form = UpdateNoteForm()
    if request.method == 'POST':
        form = UpdateNoteForm(request.form)

        if form.validate == False:
            flash('Faliure','danger')
            return redirect(url_for('profile')+('/'+current_user.slug))

        if form.validate_on_submit():

            tags = form.tags2.data
            tagList = tags.split(",")

            note = Note.objects.get(id=form.wtf.data)
            note.update(content=form.content2.data, tags=tagList, URLLink=form.URLLink2.data)

            current_user.notes.append(note)
            current_user.update(notes__tags=tagList, notes__content=form.content2.data, notes__URLLink=form.URLLink2.data)

            flash("Success","success")

    return render_template("update.html", title="delete", form=form, note=note )

traceback

   mongoengine.errors.OperationError
OperationError: Update failed (cannot use the part (notes of notes.URLLink) to traverse the element ({notes: [ { _id: ObjectId('57d27bb24d2e9b04e175c0e5'), created_at: new Date(1473422818025), URLLink: "", content: "{
    "_id" : ObjectId("57d27b414d2e9b04d79883b3"),
    "created_at" : ISODate("2016-09-09T12:05:05.164Z"),
    "URLLink" : "",
    "content" : "c...", tags: [ "asd" ], isSecret: false, isArchived: false } ]}))

Traceback (most recent call last)
File "/Users/ozer/Documents/localhost/copylighter/env/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/ozer/Documents/localhost/copylighter/env/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Users/ozer/Documents/localhost/copylighter/env/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/ozer/Documents/localhost/copylighter/env/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Users/ozer/Documents/localhost/copylighter/env/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/ozer/Documents/localhost/copylighter/env/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/ozer/Documents/localhost/copylighter/env/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/ozer/Documents/localhost/copylighter/env/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/ozer/Documents/localhost/copylighter/env/lib/python2.7/site-packages/flask_login.py", line 792, in decorated_view
return func(*args, **kwargs)
File "/Users/ozer/Google Drive/localhost/copylighter/views.py", line 225, in update_quote

                        note = Note.objects.get(id=form.wtf.data)
                        note.update(content=form.content2.data, tags=tagList, URLLink=form.URLLink2.data)

                        current_user.notes.append(note)
                        current_user.update(notes__tags=tagList, notes__content=form.content2.data, notes__URLLink=form.URLLink2.data)


                        #note.save()


File "/Users/ozer/Documents/localhost/copylighter/env/lib/python2.7/site-packages/mongoengine/document.py", line 468, in update
return self._qs.filter(**self._object_key).update_one(**kwargs)
File "/Users/ozer/Documents/localhost/copylighter/env/lib/python2.7/site-packages/mongoengine/queryset/base.py", line 490, in update_one
upsert=upsert, multi=False, write_concern=write_concern, **update)
File "/Users/ozer/Documents/localhost/copylighter/env/lib/python2.7/site-packages/mongoengine/queryset/base.py", line 472, in update
raise OperationError(u'Update failed (%s)' % unicode(err))
OperationError: Update failed (cannot use the part (notes of notes.URLLink) to traverse the element ({notes: [ { _id: ObjectId('57d27bb24d2e9b04e175c0e5'), created_at: new Date(1473422818025), URLLink: "", content: "{ "_id" : ObjectId("57d27b414d2e9b04d79883b3"), "created_at" : ISODate("2016-09-09T12:05:05.164Z"), "URLLink" : "", "content" : "c...", tags: [ "asd" ], isSecret: false, isArchived: false } ]}))

I think that's the important part that I writed below. I didn't find any quertset about it and there are few documentation about mongoengine. Where would I search for?

current_user.update(notes__tags=tagList, notes__content=form.content2.data, notes__URLLink=form.URLLink2.data)
oyilmaztekin
  • 713
  • 1
  • 7
  • 25

1 Answers1

0

You have a few issues here:

  • You can use (in the most recent versions of mongoengine) an EmbeddedDocumentListField
  • The Noteclass needs to inherit EmbeddedDocument
  • You can't use an update operation on the User object in the way you are attempting

Consider the following example which will add a note to the users note field.

import mongoengine as mdb
from numpy.random.mtrand import randint

mdb.connect("embed-test")


class User(mdb.Document):
    name = mdb.StringField()
    notes = mdb.EmbeddedDocumentListField('Note')


class Note(mdb.EmbeddedDocument):
    content = mdb.StringField(required=True)
    tags = mdb.ListField(mdb.StringField(required=True, max_length=20))


User.drop_collection()

u = User(name="Name").save()

if __name__ == "__main__":
    new_note = Note(content="Some notes here.", tags=['one', 'two'])
    current_user = User.objects.first()
    current_user.notes.append(new_note)
    current_user.save()

You may also want to read this answer on when to you use EmbeddedDocument vs. a ReferenceField.

Community
  • 1
  • 1
Steve Rossiter
  • 2,624
  • 21
  • 29
  • Thank @steve-rossiter I maked the changes but still it returns the same error in traceback. – oyilmaztekin Sep 09 '16 at 11:45
  • Ok can you edit your answer to update it with the changes you've made? – Steve Rossiter Sep 09 '16 at 11:48
  • I am sorry I can't edit my answer. So I am writing in here. When I check my code for copy it for you I realise I wasn't change my Note modal class as class Note(db.EmbeddedDocument): I did this change but now I am working on inserting Note on the shell. http://prnt.sc/cfzmxa – oyilmaztekin Sep 09 '16 at 12:00
  • You don't need to save an EmbeddedDocument you just assign it to an EmbeddedDocumentField or append it to an EmbeddedDocumentListField – Steve Rossiter Sep 09 '16 at 12:07
  • Well, my whole development process crashed right now. I am struggling to change my point of view. Would you help me to understand what is that mean "assigning to EmbeddedDocumentField" or "appending to note EmbeddedDocumentListField" without saving it? – oyilmaztekin Sep 09 '16 at 12:14
  • 1
    Can I suggest you read the [user guide](http://docs.mongoengine.org/guide/index.html)? You will need to understand the fundamentals of how mongoengine maps from mongodb documents to python objects. – Steve Rossiter Sep 09 '16 at 12:31
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/122998/discussion-between-steve-rossiter-and-oyilmaztekin). – Steve Rossiter Sep 09 '16 at 13:10