首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Tastypie中的FileField

Tastypie中的FileField
EN

Stack Overflow用户
提问于 2012-02-26 09:31:53
回答 2查看 2.4K关注 0票数 1

我有一个模型,我正在用tastypie为它做一个api。我有一个字段,其中存储了我手动维护的文件的路径(我没有使用FileField,因为用户没有上传文件)。下面是一个模型的要点:

代码语言:javascript
复制
class FooModel(models.Model):
    path = models.CharField(max_length=255, null=True)
    ...
    def getAbsPath(self):
        """
        returns the absolute path to a file stored at location self.path
        """
        ...

下面是我的品味配置:

代码语言:javascript
复制
class FooModelResource(ModelResource):
    file = fields.FileField()

    class Meta:
        queryset = FooModel.objects.all()

    def dehydrate_file(self, bundle):
        from django.core.files import File
        path = bundle.obj.getAbsPath()        
        return File(open(path, 'rb'))

在api的file字段中,这将返回文件的完整路径。我希望tastypie能够提供实际的文件,或者至少是一个文件的url。我该怎么做?任何代码片段都是受欢迎的。

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-26 23:31:08

首先确定一个URL方案,如何通过API公开您的文件。你并不真的需要file或dehydrate_file (除非你想在Tastypie中改变模型本身的文件表示)。相反,只需在ModelResource上添加一个额外的操作。示例:

代码语言:javascript
复制
class FooModelResource(ModelResource):
    file = fields.FileField()

    class Meta:
        queryset = FooModel.objects.all()

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/download%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('download_detail'), name="api_download_detail"),
            ]

    def download_detail(self, request, **kwargs):
        """
        Send a file through TastyPie without loading the whole file into
        memory at once. The FileWrapper will turn the file object into an
        iterator for chunks of 8KB.

        No need to build a bundle here only to return a file, lets look into the DB directly
        """
        filename = self._meta.queryset.get(pk=kwargs[pk]).file
        wrapper = FileWrapper(file(filename))
        response = HttpResponse(wrapper, content_type='text/plain') #or whatever type you want there
        response['Content-Length'] = os.path.getsize(filename)
        return response

GET .../api/foomodel/3/

返回:{ ...‘'file’:'localpath/filename.ext',... }

GET .../api/foomodel/3/download/

返回:实际文件的...contents ...

或者,您可以在FooModel中创建一个非ORM子资源文件。您必须定义resource_uri (如何唯一标识资源的每个实例),并覆盖dispatch_detail以执行上述download_detail所做的事情。

票数 4
EN

Stack Overflow用户

发布于 2012-02-26 23:27:16

在FileField上唯一能做的转换就是在你返回的东西上寻找一个'url‘属性,如果它存在的话,它会返回一个字符串对象,正如你已经注意到的,它只是一个文件名。

如果希望将文件内容作为字段返回,则需要处理文件的编码。您有几个选项:

  • 最简单:使用CharFieldbase64模块将从文件中读取的字节转换为字符串
  • 更通用但功能等效:编写一个自定义的、知道如何将文件对象转换为其内容的字符串表示形式的序列化程序您的资源的get_detail函数使用任何适当的内容类型仅服务于文件,以避免JSON/XML序列化开销。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9449749

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档