2012-02-26 6 views
1

나는 tastypie에서 api를 만들고있는 모델을 가지고 있습니다. 수동으로 유지하는 파일의 경로를 저장하는 필드가 있습니다 (사용자가 파일을 업로드하지 않기 때문에 FileField을 사용하지 않습니다). 파일 필드에 API의FileField in Tastypie

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

이 파일에 전체 경로를 반환

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 
     """ 
     ... 

가 여기 내 tastypie의 설정입니다 : 여기에 모델의 요점이다. tastypie가 실제 파일이나 적어도 URL을 파일에 제공 할 수 있기를 바랍니다. 어떻게해야합니까? 모든 코드 스 니펫은 높이 평가됩니다.

감사합니다

답변

4

파일을 통해 API를 통해 노출되는 방식을 URL 스키마로 결정하십시오. Tastypie에서 모델 자체의 파일 표현을 변경하지 않으려는 경우 file 또는 dehydrate_file은 실제로 필요하지 않습니다. 대신 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/

결과 : { ... '파일' '의 localpath/여기서 filename.ext', ... }

GET .../API/foomodel/3/다운로드/

결과 : ... 실제 파일의 내용 ...

또는 FooModel에서 ORM이 아닌 하위 리소스 파일을 만들 수 있습니다. resource_uri (리소스의 각 인스턴스를 고유하게 식별하는 방법)을 정의하고 dispatch_detail을 재정 의하여 위에 설명한 것과 같은 download_detail을 수행해야합니다.

+0

'FileWrapper '는 어디에서 왔습니까? –

+0

'django.core.servers.basehttp import FileWrapper' – astevanovic

+0

파일 핸들이 클라이언트로 스트리밍 된 후 파일 핸들을 닫습니까? –

0

유일한 변환 tastypie FileField와상의 'URL'을 찾아 당신이 돌아 것에 속성, 그리고 존재하는 경우, 그렇지 않으면 문자열화된 객체를 돌려 보낼 반환하는 것입니다 않는 당신이주의 한대로 파일 이름이다.

파일 내용을 필드로 반환하려면 파일의 인코딩을 처리해야합니다.

  • 간단한 : 사용 CharField
  • 보다 일반적인하지만 기능이 동일한 문자열로 파일에서 읽은 바이트를 변환 할 base64 모듈을 사용하는 방법을 알고있는 사용자 정의 tastypie의 시리얼 쓰기 당신은 몇 가지 옵션이 File 객체를 내용의 문자열 표현으로 바꾸십시오.
  • JSON/XML 직렬화 오버 헤드를 피하기 위해 적절한 content-type을 사용하여 파일을 제공하도록 자원의 get_detail 기능을 덮어 씁니다.