장고 - 관리자 사이트의 결제 정보 PDF 파일
- 온라인 쇼핑몰 사이트의 경우, 관리자페이지에서 고객의 결제 정보를 PDF로 저장하는 경우가 있다.
- 이번 포스트에서는 온라인 쇼핑몰 사이트를 예로 들어 관리자 사이트에서 고객이 주문한 상품정보를 PDF 파일로 조회 및 다운로드하는 방법에 대해 다룰 것이다.
1. Weasyprint 설치
ex) wps-onlineshop 프로젝트
- 경로 : wps-onlineshop
1 pip install weasyprint
- 설치 안되는 경우, 아래 주소로 접속하여 절차대로 실행
https://weasyprint.readthedocs.io/en/latest/install.html
2. Weasyprint 실행
- 경로 : wps-onlineshop
1
python -m weasyprint http://weasyprint.org weasyprint.pdf
3. 관리자 사이트에서 PDF 링크 설정
- 경로 : wps-onlineshop > order > admin.py
1
2
3
4
5
6
7
8
9
10from django.utils.safestring import mark_safe
def order_pdf(obj):
# pdf 파일 뷰로 가는 링크
url = resolve_url('admin_order_pdf', obj.id)
# mark_safe를 사용하여 텍스트를 html 형태로 변환
return mark_safe(f'<a href="{url}" target="_blank">pdf</a>')
# 관리자페이지에서 링크로 연결되어지는 문구를 'PDF'로 설정
order_pdf.short_description = 'PDF'
4. PDF 클릭 시, 이동할 페이지 경로 설정
- 경로 : order > urls.py
1
2
3
4
5
6from django.urls import path
from .views import *
urlpatterns = [
path('admin/pdf/<int:order_id>/', admin_order_pdf, name='admin_order_pdf'),
]
5. PDF 파일에서 보여지는 내용 작성
경로 : order > views.py
1
2
3
4
5
6
7
8
9
10
11
12
13from django.contrib.admin.views.decorators import staff_member_required
from django.template.loader import render_to_string
from django.http import HttpResponse
import weasyprint
# 유저가 로그인했다면, 그 유저가 관리자인지 확인하여 관리자가 아니라면 기존 요청한 주소로 이동되도록 @staff_member_required 사용
def admin_order_pdf(request, order_id):
order = get_object_or_404(Order, id=order_id)
html = render_to_string('order/admin/pdf.html', {'order':order})
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = f'filename=invoice_{order.id}.pdf'
weasyprint.HTML(string=html).write_pdf(response)
return response경로 : order > templates > order > admin > pdf.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49<html>
<body>
<h1>WPS Onlineshop</h1>
<p>
Invoice no. {{ order.id }}</br>
<span class="secondary">{{ order.created|date:"M d, Y" }}</span>
</p>
<h3>{% if order.paid %}Payment Accepted{% else %}Pending payment{% endif %}</h3>
<p>
{{ order.first_name }} {{ order.last_name }}<br>
{{ order.email }}<br>
{{ order.address }}<br>
{{ order.postal_code }}, {{ order.city }}
</p>
<h3>Product List</h3>
<table>
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Quantity</th>
<th>Cost</th>
</tr>
</thead>
<tbody>
{% for item in order.items.all %}
<tr class="row{% cycle '1' '2' %}">
<td>{{ item.product.name }}</td>
<td class="num">${{ item.price }}</td>
<td class="num">{{ item.quantity }}</td>
<td class="num">${{ item.get_item_price }}</td>
</tr>
{% endfor %}
{% if order.coupon %}
<tr class="discount">
<td colspan="3">Discount</td>
<td class="num">${{ order.discount }}</td>
</tr>
{% endif %}
<tr class="total">
<td colspan="3">Total</td>
<td class="num">${{ order.get_total_price }}</td>
</tr>
</tbody>
</table>
</body>
</html>
6. 관리자 사이트에 보여질 항목에 pdf 항목 추가
경로 : order > admin.py
1
2
3
4
5class OrderOption(admin.ModelAdmin):
# 관리자 사이트 항목에 'order_pdf' 추가
list_display = ['id','first_name','last_name','email','paid', order_pdf, 'created','updated']
admin.site.register(Order, OrderOption)경로 : order > models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20# order 모델 참고
from django.db import models
class Order(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField()
address1 = models.CharField(max_length=100)
address2 = models.CharField(max_length=100)
city = models.CharField(max_length=50)
postal_code = models.CharField(max_length=20)
created = models.DateTimeField(auto_now_add=True )
updated = models.DateTimeField(auto_now=True)
paid = models.BooleanField(default=False)
# 결제 시도 전에 주문을 먼저 생성한다.
class Meta:
ordering = ['-updaed']
Posted