Django Template을 사용할때 html 코드내에서는 view에서 넘어온 데이터를 사용하기 쉽다. 하지만 script 내에선 어떻게 사용할지 애매하다.
일단 https://adamj.eu/tech/2020/02/18/safely-including-data-for-javascript-in-a-django-template/ 이 블로그를 보면 잘 나와있는데 방법은 간단하다.
예제로 알아보기
Product라는 모델이 있고, 그 Product를 장바구니에 담는 예제로 알아보자
class Product(models.Model):
productTypes = [('S', 'Small'), ('R', 'Regular'), ('G', 'Grande')]
name = models.CharField(max_length=50)
price = models.IntegerField()
type = models.CharField(max_length=30, choices=productTypes, null=True)
image = models.ImageField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
components = models.ManyToManyField(ProductComponent, through='ProductRelatedComponent')
def __str__(self):
return self.name
product/model.py
def index(request):
products = Product.objects.all()
serialized_products = [{ "id": p.id, "name": p.name, "price": p.price } for p in products]
return render(request, 'product/product-list.html', {'products': serialized_products})
product/view.py
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>쇼핑몰</h2>
<div>
<ul>
{% for product in products %}
<li>
<span>{{ product.id }}. {{ product.name }}({{ product.price }}원)</span>
<button onclick="addCart('{{product.id}}')">담기</button>
</li>
{% endfor %}
</ul>
</div>
</body>
<script>
function addCart(productId) {
return alert(productId + " 상품을 담았습니다.");
}
</script>
templates/product-list.html
지금 상태로는 [담기] 버튼을 클릭하면 3 상품을 담았습니다. 이렇게 밖에 구현할 수 없다.
만약 <script> 태그 내에서 products 데이터를 사용하고 싶으면 어떻게 해야할까?
템플릿 코드의 태그 사이에 변수 | json_script: "id로 사용할 이름" 을 넣으면 된다.
{{ value|json_script:"product-data" }}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>쇼핑몰</h2>
<div>
<ul>
{% for product in products %}
<li>
<span>{{ product.id }}. {{ product.name }}({{ product.price }}원)</span>
<button onclick="addCart('{{product.id}}')">담기</button>
</li>
{% endfor %}
</ul>
</div>
{{ products|json_script:"product-data" }}
</body>
<script>
const cart = []
const products = JSON.parse(document.getElementById("product-data").textContent)
function addCart(productId) {
const product = products.find(p => p.id === Number(productId))
if (product) {
return alert(product.name + '상품을 담았습니다.');
}
}
</script>
이렇게 작성하고 렌더링된 화면의 코드를 보면 <script> 태그 안에 type=”application/json”으로 해당 데이터가 있는걸 확인할 수 있다.
이제 script안에서는 document.getElementById를 통해 값을 사용할 수 있다.
const products = JSON.parse(document.getElementById("product-data").textContent)
function addCart(productId) {
const product = products.find(p => p.id === Number(productId))
if (product) {
return alert(product.name + '상품을 담았습니다.');
}
}
주의할 점
템플릿으로 데이터를 넘길때 쿼리셋을 그대로 넘기면 값을 파싱할 수 없기 때문에 딕셔너리 형태로 값을 넘겨줘야한다.
참고
Safely Including Data for JavaScript in a Django Template - Adam Johnson
Safely Including Data for JavaScript in a Django Template 2020-02-18 Update (2022-10-06): I wrote an updated version of this post covering more techniques: How to Safely Pass Data to JavaScript in a Django Template. Django templates are often used to pass
adamj.eu
[Django] json_script 를 이용한 효과적인 json parsing
Django의 파이썬 변수를 templates 로 넘겨주기 위해서 템플릿 문법를 사용합니다. 단순히 문자열 값을 나타내기 위해서는 문제가 없지만 javascript 에서 처리를 해줘야 할 상황이 온다면 제한 사항이
ssungkang.tistory.com
'Django,Python' 카테고리의 다른 글
[Django] Custom Command 만들기 (0) | 2024.04.06 |
---|---|
[Django] on_delete=CASCADE (3) | 2024.03.23 |
[Python] 파이썬의 typing (2) | 2024.03.09 |
MAMP로 Python CGI 테스트 해보기 (1) | 2024.01.12 |
[Django] Django ORM Coalesce 사용하기 (0) | 2023.09.22 |