장고 S3이용해서 pdf 저장 후 데이터베이스에 주소 저장 기능구현(html 에서 pdf으로 변환)

이정민·2021년 7월 4일
1

대한항공을 모티브로 한 프로젝트에서 내가 맡은 역할은 항공권을 결제를 하게 되면 각 회원에 맞는 항공티켓을 제공하는 기능구현을 맡았다.

쉽게 생각했었지만 전체적인 과정을 설명하자면

  1. template디렉토리 안에 있는 html에 python변수를 넣어서 각각의 회원들의 정보들을 넣는 작업

  2. 그렇게 만들어진 html을 pdf로 변환하는 작업

  3. pdf를 AWS S3에 저장하는 작업

  4. S3에 저장되어있는 pdf파일의 주소를 Database에 저장하는 것이다.

처음으로 구현을 하다보니 여러정보 사이트에서 정보를 구하다가 결국엔 구현을 해냈다. 그 끝에는 엄청난 희열감이 있었다.

내 코드를 소개한다.

첫번째 완성했을 때 코드(코드가 깔끔하지 않다..)


# from logging import error
import boto3, json, pdfkit
from datetime import datetime

from django.views import View
from django.http  import HttpResponse
from django.template.loader import get_template
from django.core.files.base import ContentFile

from users.utils import login_decorator
from tickets.models import Passenger
from my_settings import AWS_ACCESS_KEY, AWS_SECRET_KEY

class FileView(View):

    s3_client = boto3.client(
        's3',
        aws_access_key_id = AWS_ACCESS_KEY,
        aws_secret_access_key = AWS_SECRET_KEY
    )

    # @login_decorator
    def post(self, request):
        data = json.loads(request.body)
        content = dict()
        ticket_id = data['ticket_id']
        passengers = Passenger.objects.filter(ticket_id = ticket_id)
        #input으로 filgh_id도 받아야됨

        for passenger in passengers:
            content["korean_name"]  = passenger.korean_name
            content["english_name"] = passenger.english_name
            content["phone"]        = passenger.phone
            content["passport"]     = passenger.passport
            content["flight_number"] = passenger.ticket.flight.flight_number
            content["departure_datetime"] = passenger.ticket.flight.departure_datetime
            content["arrival_datetime"] = passenger.ticket.flight.arrival_datetime
            content["duration"] = passenger.ticket.flight.duration
            content["departure_city"] = passenger.ticket.flight.departure_city.name
            content["arrival_city"] = passenger.ticket.flight.arrival_city.name
            content["departure_country"] = passenger.ticket.flight.departure_city.country.name
            content["arrival_country"] = passenger.ticket.flight.arrival_city.country.name
            content["departure_airport_code"] = passenger.ticket.flight.departure_city.airport_code
            content["arrival_airport_code"] = passenger.ticket.flight.arrival_city.airport_code
            content["price"] = passenger.ticket.flight.price

            template            = get_template('tickets/pdf.html')
            html                = template.render(content)
            pdf                 = pdfkit.from_string(html, False)
            ticket_pdf          = ContentFile(pdf)
            welcome2air_tickets = 'welcome2air_tickets'+str(datetime.now())

            self.s3_client.upload_fileobj(
                ticket_pdf,
                'welcome2air',
                welcome2air_tickets,
                ExtraArgs={
                    'ContentType' : 'application/pdf'
                }
            )
            
            file_url = f"https://s3.ap-northeast-2.amazonaws.com/{'welcome2air'}/{welcome2air_tickets}"
            
            passenger.pdf_url = file_url
            passenger.save()

        return HttpResponse(status= 200)

    # def get(self, request):




  1. 깔끔하게 바꾼 코드(변수들만 정리 했다.)

import boto3, json, pdfkit

from datetime               import datetime
from django.views           import View
from django.http            import HttpResponse
from django.template.loader import get_template
from django.core.files.base import ContentFile

from users.utils    import login_decorator
from tickets.models import Passenger
from my_settings    import AWS_ACCESS_KEY, AWS_SECRET_KEY

class FileView(View):

    s3_client = boto3.client(
        's3',
        aws_access_key_id = AWS_ACCESS_KEY,
        aws_secret_access_key = AWS_SECRET_KEY
    )

    @login_decorator
    def post(self, request):
        data = json.loads(request.body)
        content = dict()
        ticket_id = data['ticket_id']
        passengers = Passenger.objects.filter(ticket_id = ticket_id)

        for passenger in passengers:
            content = {
                "korean_name"            : passenger.korean_name,
                "english_name"           : passenger.english_name,
                "phone"                  : passenger.phone,
                "passport"               : passenger.passport,
                "flight_number"          : passenger.ticket.flight.flight_number,
                "departure_datetime"     : passenger.ticket.flight.departure_datetime,
                "arrival_datetime"       : passenger.ticket.flight.arrival_datetime,
                "duration"               : passenger.ticket.flight.duration,
                "departure_city"         : passenger.ticket.flight.departure_city.name,
                "arrival_city"           : passenger.ticket.flight.arrival_city.name,
                "departure_country"      : passenger.ticket.flight.departure_city.country.name,
                "arrival_country"        : passenger.ticket.flight.arrival_city.country.name,
                "departure_airport_code" : passenger.ticket.flight.departure_city.airport_code,
                "arrival_airport_code"   : passenger.ticket.flight.arrival_city.airport_code,
                "price"                  : passenger.ticket.flight.price
            }

            template            = get_template('tickets/pdf.html')
            html                = template.render(content)
            pdf                 = pdfkit.from_string(html, False)
            ticket_pdf          = ContentFile(pdf)
            welcome2air_tickets = 'welcome2air_tickets'+str(datetime.now())

            self.s3_client.upload_fileobj(
                ticket_pdf,
                'welcome2air',
                welcome2air_tickets,
                ExtraArgs={
                    'ContentType' : 'application/pdf'
                }
            )
            
            file_url = f"https://s3.ap-northeast-2.amazonaws.com/{'welcome2air'}/{welcome2air_tickets}"
            
            passenger.pdf_url = file_url
            passenger.save()

        return HttpResponse(status= 200)
profile
안녕하세요.

0개의 댓글