【问题标题】:Why do I getting 'FileField' object has no attribute 'put'?为什么我得到 'FileField' 对象没有属性 'put'?
【发布时间】:2010-11-18 21:52:02
【问题描述】:

按照 http://mongoengine.org/docs/v0.4/guide/gridfs.html 关于 mongoengine FileField 的文档,我做了以下事情:

在我的模型中

files = ListField(FileField())

在我的测试代码中

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

尝试关注文档,但出现错误:

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'

我是否遗漏了一些明显的东西?

谢谢

【问题讨论】:

    标签: python mongodb gridfs mongoengine


    【解决方案1】:

    这一点在 IMO 中并不明显,但是如果您查看 Mongoengine 代码,您会发现 put 方法是在 GridFSProxy 类中定义的,该类通过 FileField 中的描述符访问( __get____set__ 方法)。

    查看文档中的代码和示例,似乎访问或使用FileField 的唯一方法是通过描述符....so, collection.file_field

    考虑到这一切,我认为使用 Mongoengine API 的文件字段列表是不可能的,因为它现在存在。

    【讨论】:

      【解决方案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()
      

      【讨论】:

      • 这个答案如何将 FileFields 放入 ListField 中??
      【解决方案3】:

      如果您要上传多个文件并尝试将其保存为 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()
      

      【讨论】:

        【解决方案4】:

        我遇到了完全相同的问题。正如@KoppeKTop 在 GitHub 上的 this post 中所建议的那样,我终于使用如下 EmbeddedDocument 扩展了我的模型 (Pet):

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

        然后我可以使用添加新图像

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

        这可能并不总是最好的选择,但我个人更喜欢它,因为我可以像往常一样使用模型而无需使用代理。如果需要,我还可以在以后保存其他照片元数据。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-09-29
          • 2021-03-29
          • 2017-11-21
          • 2020-04-08
          • 2017-05-23
          相关资源
          最近更新 更多