수학과의 좌충우돌 프로그래밍

[Django] json_script 를 이용한 효과적인 json parsing 본문

웹프로그래밍/Django

[Django] json_script 를 이용한 효과적인 json parsing

ssung.k 2019. 7. 28. 01:31

Django의 파이썬 변수를 templates 로 넘겨주기 위해서 템플릿 문법를 사용합니다. 단순히 문자열 값을 나타내기 위해서는 문제가 없지만 javascript 에서 처리를 해줘야 할 상황이 온다면 제한 사항이 생깁니다. 이럴 때는 특별한 과정이 필요한데 이에 대해서 알아보도록 하겠습니다.

 

문제 발생 상황

어느 상황에서 문제가 발생했는지 전체적인 코드를 간단하게 설명해드리겠습니다.

models.py

from django.db import models

# Create your models here.
class Profile(models.Model):
    name = models.CharField(max_length=10)

    def __str__(self):
        return self.name

    def as_dict(self):
        return {'name'+str(self.id) : self.name}

테스트를 해보기 위한 Profile 모델을 정의하였습니다. 메소드로는 name 을 dictionary 형태로 변환해주는 as_dict 가 있습니다.

view.py

from django.shortcuts import render
from .models import Profile

# Create your views here.
def index(request):
    profile_list = Profile.objects.all()
    profile_dict = {}
    for profile in profile_list:
        profile_dict["name"+str(profile.id)] = profile.name

    context = {
        'profile_dict': profile_dict,
    }
    return render(request, 'myapp/index.html' , context)

모든 Profile 객체들을 가지고 와서 이를 dictionary 형태로 다시 저장합니다.

profile_dict # {'name1': '강민성', 'name2': '홍길동'}

profile_dict 의 값은 다음과 같습니다.

index.html

javascript 에서 해당 데이터를 처리하기 위해서 템플릿 태그로 가져왔습니다.

var profile = "{{profile_dict}}";
// {'name1': '강민성', 'name2': '홍길동'}

이는 type 도 string 일 뿐만 아니라 아포스트로피(작은 따음표) 가 &#39 다음과 같이 변한 걸 확인할 수 있습니다. &#39 를 escape 코드라고 합니다. 변환을 하는 이유는 XSS 공격 에 대해서 대응하기 위해서 입니다. XSS 공격 에 대해서는 다음에 알아보도록 하겠습니다.

escape 코드란?

이스케이프 코드란 프로그래밍할 때 사용할 수 있도록 미리 정의해 둔 "문자 조합"이다.

 

replace 를 이용해서 해결

첫번째 방법으로는 replace 를 이용해서 해결할 수 있습니다.

var profile = "{{profile_dict}}".replace(/'/g, "\"");
// {"name1": "강민성", "name2": "홍길동"}

escape 코드를 " 다음으로 대체함으로서 우리가 원하는 데이터 형태를 얻을 수 있습니다.

 

json_script 를 이용해서 해결

이는 templates filter 입니다. 이는 파이썬 객체를 JSON 으로 출력을 해줍니다.

{{ profile_dict | json_script:"dict-id"}}    

<script id="dict-id" type="application/json">{"name1": "\uac15\ubbfc\uc131", "name2": "\ud64d\uae38\ub3d9"}</script>

son_script 를 통해서 <script>태그로 감싸져있고 id 값을 dict-id 를 가지는 태그를 만들게 됩니다.

var profile = document.getElementById("dict-id").textContent;

// {"name1": "\uac15\ubbfc\uc131", "name2": "\ud64d\uae38\ub3d9"}

이를 id 값을 이용해서 가져오면 다음과 같은 값을 얻을 수 있습니다.

 

JSON parsing

이제 마지막으로 parsing 후 데이터를 사용하는 일만 남았습니다.

parsing 이란?

다른 형식으로 저장된 데이터를 원하는 형식의 데이터로 변환하는 것으로서 형변환과는 헷갈려서는 안됩니다.

var profileJson = JSON.parse(profile);

profileJson['name1'] // 강민성

위에서 얻은 profile 에 대하여 parsing 을 해줌으로서 json 으로 타입을 바꾸면 dictionary 에 대해서 key 값으로 value 값에 접근하는 것도 문제없이 할 수 있습니다.

 

Comments