[Django 첫번째 프로젝트 - 웹 크롤러 만들기]

4) Django 모델 자바스크립트에서 JSON 파일로 가져오기

Y-Joo 2021. 4. 14. 23:17

 지난 포스트에서 디자인적인 부분은 많이 개선되었고, 이제 남은건 크롤링한 데이터를 넣고 크론탭으로 자동화를 시킨 후 배포하는 것이다. 크롤링하는 과정은 협업하는 친구가 맡아 Django 모델에 JSONField로 딕셔너리 형태로 넣어주었다.

class BlogData(models.Model):
    title = models.CharField(max_length=200)
    content = models.JSONField(default=dict)
BlogData.objects.all().delete()
BlogData(title="COIN_DATA", content=json.dumps(preprocessingDict(result.copy()))).save()

첫번째 코드는 Django 모델, 두번째는 cron.py에서 모델에 데이터를 넣는 코드이다. 항상 모델의 개수는 하나로 고정시키기 위해 새로운 값을 얻을때메다 전에 있던 데이터는 삭제하는 delete() 함수를 넣었다. 또한 딕셔너리인 result를 json.dumps로 감싸 JSONField인 content에 맞게 값을 넘겨주었다. 이제 이렇게 넘긴 JSON파일을 JS에서 받으면 되는데, 

<script>
        let posts = [
            {% for post in BlogDatas %}
              {
                 coindict: JSON.parse("{{ post.content | escapejs }}")
              },
            {% endfor %}
        ]
</script>

이 코드를 이용했다. Blogdatas는 view에서 선언했는데,

def BlogData_list(request):
    context = {
        "BlogDatas": BlogData.objects.all()
    }
    return render(request, 'crawled_data/coin_calender.html', context)

html로부터 요청을 받으면 Blogdata, 즉 모델에 들어있는 모든 값을 리턴하는 변수이다.

다시 script 내의 코드를 보면 모델에 있는 모든 값을 돌며 각 post는 coindict라는 변수에 post.content라는 JSON파일을 parse해서 딕셔너리 형태로 저장한다. 하지만 아까 말했듯 Blogdata의 개수는 하나로 지정해놨기 때문에 posts배열은 길이가 하나인 배열로 고정되고, 내가 원하는 딕셔너리를 얻기 위해서는 posts[0]만 접근하면 되는 것이다. 

function addnews(key, key_2) {
        var news_date = document.getElementById(key);
        if (!news_date) {
            return
        }
        const new_text = document.createTextNode(key_2);
        const newdiv = document.createElement('div');
        newdiv.setAttribute('class', 'coin_name');

        newdiv.appendChild(new_text);
        newdiv.style.color = 'black';
        news_date.appendChild(newdiv);
        newdiv.addEventListener('click', function () {
            detail.innerHTML = "";
            let divEls = document.querySelectorAll('.detail > div');
            for (let i = 0; i < divEls.length; i++) {
                divEls[i].remove();
            }

            for (let i = 0; i < posts[0].coindict[key][key_2].length; i++) {
                (function (m) {
                    const dat = posts[0].coindict[key][key_2][m];
                    const coin_link = dat[0];
                    const coin_title = dat[1];

                    const link_text = document.createTextNode(coin_link);
                    const link_div = document.createElement('a');
                    link_div.setAttribute('href', coin_link);
                    link_div.setAttribute('target', "_blank");
                    link_div.appendChild(link_text);
                    link_div.setAttribute('class', 'coin_link');
                    detail.innerHTML += coin_title + '<br>';
                    detail.appendChild(link_div);
                    detail.innerHTML += '<br>' + '<br>';
                })(i);
            }
            detail.style.display = 'block';
        })
    }

 이 코드는 해당되는 날짜에서 실행되는 코드이다. 각 날짜에 코인 이름이 들어가고, 코인 이름을 누르면 eventlistener에 의해 뉴스의 타이틀과 링크가 제공된다. 링크는 a태그를 이용해 하이퍼링크 처리를 해주었고, target='_blank'를 이용해 현재 윈도우가 아닌 새 윈도우에서 링크가 열리게 설정했다. 

 

 아마 다음 포스트는 배포에 관한 포스트가 될 듯 싶다. 오래 걸리고 어려웠던 만큼 힘들었던 부분들을 자세히 적어 잊지 않도록 해야겠다.