2010-11-18 23 views
0

Après http://mongoengine.org/docs/v0.4/guide/gridfs.html documentation sur mongoengine FileField j'ai fait ce qui suit:Pourquoi l'objet 'FileField' n'a pas d'attribut 'put'?

Dans mon modèle

files = ListField(FileField()) 

Dans mon code de test

# Create an entry 
    photo = FileField() 
    f = open('/home/foo/marmot.jpg', 'r') 
    photo.put(f, content_type='image/jpeg') 
    entry.files = [photo,] 

Essayer de suivre la doc, mais je reçois une erreur:

Traceback (most recent call last): 
    File "/home/bar/tests.py", line 76, in test_MongoDGACLogook_creation 
    photo.put(f, content_type='image/jpeg') 
AttributeError: 'FileField' object has no attribute 'put' 

Je suis heureux Quelque chose d'évident?

Merci

Répondre

2
f = mongoengine.fields.GridFSProxy() 
    to_read = open('/home/.../marmot.jpg', 'r') 
    f.put(to_read, filename=os.path.basename(to_read.name)) 
    to_read.close() 
+0

Comment cette réponse place-t-elle FileFields dans ListField ?? – MFB

2

Ce n'est pas évident du tout de l'OMI, mais si vous regardez le code Mongoengine vous verrez que la méthode put est définie dans la classe GridFSProxy, qui est accessible via un descripteur dans FileField (les méthodes __get__ et __set__).

En regardant le code et les exemples dans les documents, il semble que la seule façon d'accéder ou d'utiliser un FileField est à travers le descripteur .... alors, collection.file_field. Etant donné tout cela, je ne pense pas qu'il soit possible d'avoir une liste de champs de fichiers utilisant l'API Mongoengine telle qu'elle existe actuellement.

0

Si vous téléchargez des fichiers multiples et en essayant de sauver un ListField (FileField())

<input type='file' name='myfiles' multiple=""> 

files = [] 
for f in request.FILES.getlist('myfiles'): 
    mf = mongoengine.fields.GridFSProxy() 
    mf.put(f, filename=f.name) 
    files.append(mf) 
entry.files = files 
entry.save() 
0

J'ai eu exactement le même problème. Comme l'a suggéré @KoppeKTop sur GitHub dans this post, je me suis finalement étendu mon modèle (Pet) en utilisant un EmbeddedDocument comme ceci:

class OneImage(mongoengine.EmbeddedDocument): 
    element = ImageField() 

class Pet(mongoengine.Document): 
    photos = EmbeddedDocumentListField(OneImage) 
    # ...more fields... # 

Je peux alors ajouter une nouvelle image à l'aide

i = OneImage() 
    i.element.put(form.photo.data.stream) 
    entry.photos.append(i) 
    entry.save() 

Cela ne peut pas toujours être la meilleure option, mais personnellement, je préfère parce que je peux travailler avec des modèles comme d'habitude sans avoir à travailler avec des proxies. Et je peux aussi enregistrer d'autres métadonnées de photos à l'avenir, si j'en ai besoin.