我有一个模型,我正在用tastypie为它做一个api。我有一个字段,其中存储了我手动维护的文件的路径(我没有使用FileField,因为用户没有上传文件)。下面是一个模型的要点:
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
"""
...下面是我的品味配置:
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。我该怎么做?任何代码片段都是受欢迎的。
谢谢
发布于 2012-02-26 23:31:08
首先确定一个URL方案,如何通过API公开您的文件。你并不真的需要file或dehydrate_file (除非你想在Tastypie中改变模型本身的文件表示)。相反,只需在ModelResource上添加一个额外的操作。示例:
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 responseGET .../api/foomodel/3/
返回:{ ...‘'file’:'localpath/filename.ext',... }
GET .../api/foomodel/3/download/
返回:实际文件的...contents ...
或者,您可以在FooModel中创建一个非ORM子资源文件。您必须定义resource_uri (如何唯一标识资源的每个实例),并覆盖dispatch_detail以执行上述download_detail所做的事情。
发布于 2012-02-26 23:27:16
在FileField上唯一能做的转换就是在你返回的东西上寻找一个'url‘属性,如果它存在的话,它会返回一个字符串对象,正如你已经注意到的,它只是一个文件名。
如果希望将文件内容作为字段返回,则需要处理文件的编码。您有几个选项:
CharField和base64模块将从文件中读取的字节转换为字符串get_detail函数使用任何适当的内容类型仅服务于文件,以避免JSON/XML序列化开销。https://stackoverflow.com/questions/9449749
复制相似问题