Update a MongoEngine document using a python dict?

前端 未结 6 997
我在风中等你
我在风中等你 2021-02-05 18:24

Is it possible to update a MongoEngine document using a python dict?

For example:

class Pets(EmbeddedDocument):
    name = StringField()

class Person(Do         


        
6条回答
  •  我在风中等你
    2021-02-05 18:49

    Here is a function to update documents with EmbeddedDocuments. It is based upon @rednaw's solution, though accounts for EmbeddedDocuments having EmbeddedDocuments.

    from mongoengine.fields import *
    
    def field_value(field, value):
      ''' 
      Converts a supplied value to the type required by the field.
      If the field requires a EmbeddedDocument the EmbeddedDocument
      is created and updated using the supplied data.
      '''
      if field.__class__ in (ListField, SortedListField):
        # return a list of the field values 
        return [
          field_value(field.field, item) 
          for item in value]
    
      elif field.__class__ in (
        EmbeddedDocumentField,
        GenericEmbeddedDocumentField,
        ReferenceField,
        GenericReferenceField):
    
        embedded_doc = field.document_type()
        update_document(embedded_doc, value)
        return embedded_doc
      else:
        return value
    
    
    def update_document(doc, data):
      ''' Update an document to match the supplied dictionary.
      '''
      for key, value in data.iteritems():
    
        if hasattr(doc, key):
            value = field_value(doc._fields[key], value)
            setattr(doc, key, value)
        else:
            # handle invalid key
            pass
    
      return doc
    

    The key here is the field_value method updating an embedded document rather than instantiating it with the data.

    Usage Example :

    class Pets(EmbeddedDocument):
        name = StringField()
    
    class Person(EmbeddedDocument):
        name = StringField()
        address = StringField()
        pets = ListField(EmbeddedDocumentField(Pets))
    
    class Group(Document):
        name = StringField()
        members = ListField(EmbeddedDocumentField(Person))
    
    g = Group()
    
    update_document(g, {
      'name': 'Coding Buddies',
      'members': [
        {
          'name': 'Dawson',
          'address': 'Somewhere in Nova Scotia',
          'pets': [
            {
              'name': 'Sparkles'
            }
          ]
        },
        {
          'name': 'rednaw',
          'address': 'Not too sure?',
          'pets': [
            {
              'name': 'Fluffy'
            }
          ]
        }
      ]
    })
    

    FYI That's actually my cat's name.

    EDIT : typo in variable names.

提交回复
热议问题