Perché mi ricevendo oggetto 'FileField' non ha alcun attributo 'put'?
-
26-09-2019 - |
Domanda
A seguito di http://mongoengine.org/docs/v0.4/guide /gridfs.html documentazione su mongoengine FileField ho fatto il seguente:
Nel mio modello
files = ListField(FileField())
Nel mio codice di prova
# Create an entry
photo = FileField()
f = open('/home/foo/marmot.jpg', 'r')
photo.put(f, content_type='image/jpeg')
entry.files = [photo,]
Cercando di seguire il doc, ma ottengo un errore:
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'
Mi sto perdendo qualcosa di ovvio?
Grazie
Soluzione 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()
Altri suggerimenti
Questa non è evidente a tutti IMO, ma se si guarda il codice Mongoengine vedrete che il metodo put
è definito nella classe GridFSProxy
, cui si accede attraverso un descrittore in FileField
(i __get__
e __set__
metodi) .
Guardando il codice e gli esempi nella documentazione, sembra che l'unico modo per accedere o utilizzare un FileField
è attraverso il descrittore .... così, collection.file_field
.
Dato tutto questo, non credo che sia possibile avere un elenco di campi di file utilizzando l'API Mongoengine come lo conosciamo oggi.
Se sono multipli caricamento dei file e cercare di salvare 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()
Ho avuto esattamente lo stesso problema. Come suggerito da @KoppeKTop su GitHub in questo post , ho finalmente esteso il mio modello (Pet
) utilizzando un EmbeddedDocument in questo modo:
class OneImage(mongoengine.EmbeddedDocument):
element = ImageField()
class Pet(mongoengine.Document):
photos = EmbeddedDocumentListField(OneImage)
# ...more fields... #
Posso quindi aggiungere una nuova immagine usando
i = OneImage()
i.element.put(form.photo.data.stream)
entry.photos.append(i)
entry.save()
Questo non può essere sempre l'opzione migliore, ma personalmente preferisco perché posso lavorare con modelli come al solito, senza dover lavorare con i proxy. E posso anche salvare altri metadati foto in futuro, se ho bisogno di.