coulix
coulix

Reputation: 3368

Why do I getting 'FileField' object has no attribute 'put'?

Following http://mongoengine.org/docs/v0.4/guide/gridfs.html documentation about mongoengine FileField I did the following:

In my model

files = ListField(FileField())

In my test code

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

Trying to follow the doc, however i get an error:

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'

Am I missing something obvious ?

Thanks

Upvotes: 0

Views: 3446

Answers (4)

Hippo
Hippo

Reputation: 510

I had exactly the same problem. As suggested by @KoppeKTop on GitHub in this post, I finally extended my model (Pet) using an EmbeddedDocument like this:

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

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

I can then add a new image using

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

This may not always be the best option, but personally I prefer it because I can work with models as usual without having to work with proxies. And I can also save other photo metadata in the future, if I need to.

Upvotes: 0

Rag Sagar
Rag Sagar

Reputation: 2374

If you are uploading multiples files and trying to save it a 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()

Upvotes: 0

coulix
coulix

Reputation: 3368

    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()

Upvotes: 2

brianz
brianz

Reputation: 7428

This isn't obvious at all IMO, but if you look at the Mongoengine code you'll see that the put method is defined in the GridFSProxy class, which is accessed via a descriptor in FileField (the __get__ and __set__ methods).

Looking at the code and the examples in the docs, it appears the only way to access or use a FileField is through the descriptor....so, collection.file_field.

Given all this, I don't think it's possible to have a list of file fields using the Mongoengine API as it exists now.

Upvotes: 2

Related Questions