Por que estou recebendo o objeto 'filefield' não tem atributo 'put'?
-
26-09-2019 - |
Pergunta
Seguindo http://mongoengine.org/docs/v0.4/guide/gridfs.html Documentação sobre Mongoengine FileField Eu fiz o seguinte:
No meu modelo
files = ListField(FileField())
No meu código de teste
# Create an entry
photo = FileField()
f = open('/home/foo/marmot.jpg', 'r')
photo.put(f, content_type='image/jpeg')
entry.files = [photo,]
Tentando seguir o médico, no entanto, recebo um erro:
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'
Estou perdendo algo óbvio?
Obrigado
Solução 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()
Outras dicas
Isso não é óbvio na IMO, mas se você olhar para o código do Mongoengine, verá que o put
o método é definido no GridFSProxy
classe, que é acessada através de um descritor em FileField
(a __get__
e __set__
métodos).
Olhando para o código e os exemplos nos documentos, parece a única maneira de acessar ou usar um FileField
é através do descritor .... então, collection.file_field
.
Dado tudo isso, acho que não é possível ter uma lista de campos de arquivo usando a API Mongoengine como existe agora.
Se você estiver enviando arquivos múltiplos e tentando salvá -lo em um campo de list (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()
Eu tive exatamente o mesmo problema. Conforme sugerido por @koppektop no github em esta postagem, Finalmente estendi meu modelo (Pet
) Usando um documento incorporado como este:
class OneImage(mongoengine.EmbeddedDocument):
element = ImageField()
class Pet(mongoengine.Document):
photos = EmbeddedDocumentListField(OneImage)
# ...more fields... #
Eu posso então adicionar uma nova imagem usando
i = OneImage()
i.element.put(form.photo.data.stream)
entry.photos.append(i)
entry.save()
Essa nem sempre é a melhor opção, mas pessoalmente eu prefiro, porque posso trabalhar com modelos como de costume sem ter que trabalhar com proxies. E também posso salvar outros metadados fotográficos no futuro, se precisar.