2017-04-12 4 views
1

reportlab을 사용하여 PDF를 생성하고 FileField에 저장해야하는 장고 앱을 작성하고 있습니다. 내 문제는 내 미디어가 S3에 저장되어 있으며이 PDF를 S3에 직접 저장하는 방법을 모른다는 것입니다.Django/reportlab : 생성 된 pdf를 AWS s3의 FileField에 직접 저장합니다.

로컬로 pdf 파일을 만들고 s3의 FileField에 저장 한 다음 로컬 버전을 삭제하지만 더 나은 솔루션이 있으면 S3에 직접 파일을 저장할 수 있는지 궁금합니다. 다음과 같이 정의된다

#temporary folder name to generate contract locally 
folder_name = (
    '/tmp/' 
    + '/contracts/' 
    + gig.identifier 
    ) 
mkdir_p(folder_name) 
address = (
    folder_name 
    + '/contract_' 
    + lang 
    + '.pdf' 
) 
doc = SimpleDocTemplate(
    address, 
    pagesize=A4, 
    rightMargin=72, 
    leftMargin=72, 
    topMargin=120, 
    bottomMargin=18 
) 
doc.build(Story, 
      canvasmaker=LogoCanvas) 
local_file = open(address) 
pdf_file = File(local_file) 
contract = Contract.objects.create(lang=lang, gig=gig) 
contract.contract_file.save('contract_'+lang+'.pdf', pdf_file) 
contract.save() 
#remove temporary folder 
shutil.rmtree(folder_name) 
return True 

및 계약 모델 :

class Contract(models.Model): 
    gig = models.ForeignKey(Gig, related_name='contracts') 
    lang = models.CharField(max_length=10, default='') 
    contract_file = models.FileField(
     upload_to=get_contract_path, 
     blank=True, 
     null=True, 
     default=None 
    ) 

답변

0

당신은 파일 대신 메모리 스트림을 생성하기위한 BytesIO을 사용할 수 있습니다 여기에

내가 지금 계약을 생성하는 방법 흐름.

그러나 파일 대신 해당 스트림을 사용하려면 reportlab을 작성해야합니다.

캔버스에 대한 2.2보다에서의 userguide에 의존, 캔버스 생성자는 문자열 또는 파일 기술자 모두가 될 수 filename 매개 변수가 있습니다. 나는 SimpleDocTemplate로 테스트 한, 그래서 당신을 위해 작동합니다 :

import io 
stream = io.BytesIO() 
doc = SimpleDocTemplate(
    stream, 
    pagesize=A4, 
    rightMargin=72, 
    leftMargin=72, 
    topMargin=120, 
    bottomMargin=18 
) 
doc.build(Story, 
      canvasmaker=LogoCanvas) 
pdf_buffer = stream.getBuffer() 

내가 S3를 모르겠지만, 나는이 문제를 해결하기에 충분 확신 해요. 예를 들어,이 pdf를 파일에 쓰려면 다음을 입력하십시오.

file = open("contract.pdf", "wb") 
file.write(pdf_buffer)