Определите схему URL, как ваши файлы будут отображаться через API в первую очередь. Вам на самом деле не нужен файл или файл 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 response
GET ... / api / foomodel / 3 /
Возвращает:
{
...
'file': 'localpath / filename.ext',
...
}
GET ... / api / foomodel / 3 / загрузить /
Возвращает:
... содержимое файла ...
В качестве альтернативы вы можете создать файл подресурса не-ORM в FooModel. Вам нужно будет определить resource_uri
(как уникально идентифицировать каждый экземпляр ресурса) и переопределить dispatch_detail, чтобы сделать именно то, что делает download_detail выше.