2019.05.18 jquery & ajax를 활용하여 댓글 구현하기입니다.

  • 패스트캠퍼스 웹 프로그래밍 스쿨 수업 정리 내용

목표

  • 댓글을 달 때 ajax가 작동하여 새롭게 페이지가 리로드 되지 않게 하기
  • ajax를 통해 단 댓글을 해당 DB에 저장하고
  • 그 댓글만을 가지고와서 댓글창의 가장 상단에 끼워넣기

로직

  • 먼저 해당 댓글 입렴 폼의 태그를 확인한다.
  • 그리고 그 폼의 submit을 눌렀을 때 해당 변화가 없도록 막고
    • submit의 경우 return false를 활용한다.
  • url을 지정하고 serialize를 통해 현재 폼에 담겨져 있는 값들을 가지고 온다.
  • ajax를 통해 url이 작동하도록 하고 해당 url을 views로 연결하여
  • 해당 views.py(댓글 구현 뷰)에서 처리할 수 있도록 한다.
  • 해당 뷰에서 처리 이후에 해당 채워넣을 부분의 html을 반환해줄 수 있도록 comment_single.html을 구현한다.
  • 그리고 뷰에서 그 html파일을 JsonResponse를 통해 반환해준다.
  • 다시 해당 템플릿에서 .done 부분에 prepend(가장 상단에 넣어주기)를 통해 해당 파일을 넣는다.

1. 해당 댓글 입력폼의 태그 확인하기

<form action="{ % url "board:comment" object.id % }" method="POST" id="comment_form">
{ % csrf_token % }
<input type="hidden" name="is_ajax" value="">
    {{comment_form.as_p}}
    <input type="submit" value="Comment" class="btn btn-outline-primary">

</form>

<table class="table table-striped" id="comment_list">
    <tbody>
    { % for comment in comments % }
   <tr>
        <td>{{ comment.text }}</td>
        <td>{{ comment.author.username}}</td>
        <td>{{ comment.created }}</td>
        <td><a href="{ % url 'board:comment_delete' comment.id % }">삭제하기</a></td>
        <td><a href="{ % url 'board:comment_update' comment.id % }">수정하기</a></td>
    </tr>
    { % endfor % }
    </tbody>
</table>

2. 그 폼의 submit을 눌렀을 때 해당 변화가 없도록 막는다.

{ % block extra_script % }
<script type="text/javascript">
    $(function () {
        $('#comment_form').submit(function(e){
            alert('댓글쓰기 완료');
            return false;   //이게 없으면 다시 리로드 되서 다녀온다.
        });
    });

</script>
{ % endblock % }

3. url을 지정하고 serialize를 통해 현재 폼에 담겨져 있는 값들을 가지고 온다.

  • url의 경우 기존에 연결되어 있는 url을 활용한다.
  • serialize를 통해 현재 폼에 담겨져 있는 값들을 가지고 온다.

4. views.py 완성하기

def comment(request, document_id):
    is_ajax = request.POST.get('is_ajax')

    document = get_object_or_404(Document, pk=document_id)

    comment_form = CommentForm(request.POST)
    comment_form.instance.author_id = request.user.id
    comment_form.instance.document_id = document_id
    if comment_form.is_valid():
        comment = comment_form.save()

    if is_ajax:
        html = render_to_string('board/comment/comment_single.html',
                                {'comment':comment})
        return JsonResponse({'html':html})

    return redirect(document)
  • is_ajax를 POST를 통해 is_ajax를 받는다. html의 jquery가 제대로 작동했다면 1을 가지고 있다.
  • 해당 새롭게 생긴 댓글을 넣어주기 위한 간단한 html을 새롭게 제작한다.
    • 만약 is_ajax가 있다면 html은 single.html을 rendering하고 위에 comment와 함께 넘겨줄 수 있도록 한다.
    • JsonResponse를 통해 html을 넘겨준다.

comment/comment_single.html

    <tr class="comment_row">
        <td class="comment_text">{{ comment.text }}</td>
        <td>{{ comment.author.username}}</td>
        <td>{{ comment.created }}</td>
        <td><a href="{ % url 'board:comment_delete' comment.id % }" class="btn_comment_delete">삭제하기</a></td>
        <td><a href="{ % url 'board:comment_update' comment.id % }" class="btn_comment_update">수정하기</a></td>
    </tr>
  • 해당 페이지를 통해 가장 위에 끼워 넣을 댓글을 만들어낸다.

5. jquery 완성하기


{ % block extra_script % }
<script type="text/javascript">
    $(function () {
        $('#comment_form').submit(function(e){
            $('input[name="is_ajax"]').val("1")
            // alert('댓글쓰기 완료');
            url = $(this).attr('action'); //원래 다녀와야하는 url
            params = $(this).serialize(); //현재 폼에 담겨있는 값들을 가지고 올 수 있게 해준다.
            $.ajax({
                url:url,
                method : "POST",
                data: params,

            }).done(function(data){
                $('#id_text').val("");
                $('#comment_list tbody').prepend(data.html); //tbody 시작지점에 요소 끼워넣기
                //$('comment_list tbody').append(tr); //tbody 끝 지점에 요소 끼워넣기
                // is_ajax 값 초기화
                $('input[name="is_ajax"]').val("");
            });

            return false;   //이게 없으면 다시 리로드 되서 다녀온다.
        });
</script>
{ % endblock % }
  • 해석하기
    • comment_form이라는 id를 가진 곳에서 submit을 누르면 막는다.(e, return false)
    • is_ajax라는 이름에 1의 값을 부여해준다.
    • url은 원래 이동하는 url로 설정한다.
    • params는 serialize()를 통해 현재 폼에 담겨 있는 값들을 가지고 올 수 있게 한다.
    • ajax를 url 요청이 위에 정의해놓은 url로 왔을 때 그리고 method는 POST방식으로 왔을 때 작동한다.
    • data는 params를 받는다.
    • 위의 ajax를 통해 URLConf를 통해 views.py를 다녀오고 JsonResponse를 통해 해당 데이터를 반환 받는다.
    • params도 views.py를 통해 data : params로 넣어서 보내준다.
    • 야는 왜 id_text 값을 어디에서도 설정해주지 않았는데 적었던 데이터가 사라지는 것일까?
      • 폼 형태로 끼워넣으면 알아서 id_text가 설정된다.

댓글달기 전체 과정보기

  • submit이 일어나면 is_ajax를 1로 바꾼다.
  • url 은 댓글남기기 페이지 주소를 가지고 온다.
  • params = serialize를 통해 폼에 있는 데이터들을 하나로 붙인다.
  • 리 다이렉션이 안되고 데이터를 추가로 가지고 오고 싶퍼서 is_ajax를 설정한 것이다.
  • 뷰에서 is_ajax이 있으면 return Jsonresponse를 하고
  • 아니면 redirect를 하도록 한다.

2019.05.17 jquery & ajax 기본 문법

  • 패스트캠퍼스 웹 프로그래밍 스쿨 수업 정리 내용

jquery & ajax 기본 문법

<script type = "text/javascript">
    $(function(){
        $('특정 테그').특정모션(function(e){
            e.preventDefault(); //일어날 행동을 일단 막고
            url = $(this).attr('href')
            data = #정의 할 데이터가 있을 때 정의
            $.ajax({
                url : url
                data : data #넘겨줄 데이터가 있을 때 적는다.
            }).done(funtion(data){
                ajax실행 뒤에 일어날 행동 정의(html 단에서)
    });
}};
</script>
  • 특정한 테그 혹은 class혹은 id에 어떤 모션이 일어났을 때(click, submit 등)
  • 원래 일어나는 행동을 막고
  • 이후에 필요로 쓰게될 특정 데이터 혹은 url에 대해 정의 해준 다음에
  • ajax를 실행시켜 ajax가 설정된 url을 통해 view를 실행시켜 해당 뷰가 db를 정리 한뒤에 필요한 것은 JsonResponse로 반환해주고 그 반환 값을 ajax에서는 받아와
  • .done뒤에 일어날 행동들을 설정해서 html 단에서 일어나는 행동들을 정의시켜준다.

ajax 기본 연습하기 (간단한 데이터 삽입해보기)

python views.py 만들기

  • 바꿔 끼울 데이터를 딕셔너리 형태로 입력해준다.
  • 일반적인 경우 데이터를 전송하기 위해 json형태로 데이터를 보낸다.
  • 따라서 jsonResponse를 활용한다.
  • json은 딕셔너리 형태로 데이터를 전송한다.
from django.http import JsonResponse

def get_data_ajax(request):
    data = {
        "name":'jake',
        "age":100,
        "blood":"O",
    }
    return JsonResponse(data)

해당 url을 연결시켜준다.

path('ajax/get_data/', get_data_ajax, name='get_data_ajax')

템플릿에 데이터 들어갈 곳 및 버튼 추가하기

<div class = "data_area">
    데이터 입력될 곳
</div>

<a href="{ % url 'board:get_data_ajax' % }" class="btn_get_data btn btn-primary">데이터 가져오기</a>

템플릿에 jquery 추가하기

  1. 먼저 url을 연결해준다.
  2. 다음으로 버튼을 눌렀을 때 이동하지 않도록 한다.
  3. 다음으로 데이터를 가지고 와야 한다.
  4. base.html에 script아래 extra_script를 추가해준다.
    1. jquery 다운로드 사이트에 접속하여 jquery를 가지고 온다.
    2. base.html에 있는 slim jquery를 바꾸어 줘야 한다.
  5. script type을 추가해준다.

{ % block extra_script % }
<script type="text/javascript">
    $(function(){
        $('.btn_get_data').click(function (e) {
            e.preventDefault(); //버튼이 클릭하면 이동못하게 기본 기능 취소
            alert('clicked'); //확인을 위해 알림창 띄우기
            url = $(this).attr('href');   //this는 이벤트 대상(btn_get_data)
            $.ajax({
                // ajax 호출시 사용할 매개변수
                url:url
            }).done(function(data){
                // 호출이 끝나면 받은 데이터를 처리하는 부분
                alert(data.name);
                // 새로운 데이터를 추가해주고 싶을 때

                name = data.name;
                age = data.age;
                bloodtype = data.bloodtype;
                html = "<ul><li>"+name+"</li><li>"+age+"</li><li>"+bloodtype+"</li></ul>"
                $('.data_area').html(html)
            });
        });
    });

</script>
{ % endblock % }
  • 해당 동작이 일어날 페이지 아래에 위의 내용을 끼워넣는다. block extra_script의 경우 base.html에서 미리 지정해놓는다.
  • 해석하기
    • .btn_get_data 클래스가 지정된 것을 찾아 만약에 클릭이 되면
    • 일단 일어날 일을 막고
    • clicked가 된 알람창을 띄어줘라
    • 그리고 이후에 사용하게 될 것들을 지정해주는데
    • url은 그 이벤트가 일어난 것에 연결된 링크를 연결해서 사용한다.
      • 아마 보통 어떤 형태가 일어나기 위해서는 링크가 연결되어야 하기 때문에 대부분 링크가 있을 것이다.
    • ajax를 실행하고
    • ajax가 실행될 때 url은 위에서 설정된 url을 바탕으로 URLSConf를 바탕으로 해당 views.py로 찾아가고
    • views.py에서 넣어놓은 data를 JsonResponse로 넘겨서 받아온다.
    • 그 받아온 데이터를 done(function(data)를 통해 가지고 오고
    • name와 age/ bloodtype에 넣어서 그 값들을 html 태그 속에 넣는다.
    • 그리고 지정된 class="data_area" 위치를 찾아가서 해당 html을 채워넣고 화면에 보여준다.

2019.04.25 동적크롤링(Ajax, JSON)

# 질문에 답하기

  1. 동적크롤링
  2. Ajax
  3. JSON

동적크롤링의 큰 그림

  • 자바스크립트로 동작되는 애들은 지속적으로 데이터를 가지고 와서 업데이트 한다.
  • 따라서 현재 보이는 데이터를 기준으로 하면 안되고 그 원본 데이터의 주소를 찾아야 한다.
  • 먼저 해당 데이터를 불러오는 url을 찾는 것이 중요한데 그것은 network에서 확인할 수 있다.
  • XHR을 선택하면 아이젝스로만 활동하는 것을 확인할 수 있고, 거기서 해당 내용을 불러오는 url을 구성한다.
  • 그리고 그 url을 통해서 크롤링을 진행해야 하며 동적데이터이기 때문에 이럴 때 이용해야 하는 것은 json이다.

Introduction

  • 브라우저(웹클라이언트)에서 웹페이지를 요청하거나 링크를 클릭하면 화면전환이 발생하는데 이것은 브라우저와 서버와의 통신에 의한 것이다.
  • 서버는 요청받은 페이지(HTML)를 반환하는데 이때 HTML 뿐만 아니라 CSS 및 javascript파일들도 함께 반환한다.
  • 웹페이지가 반환되면 브라우저(웹클라이언트)는 page를 reload하여 화면을 보여준다.
  • 서버는 요청받은 페이지가 무엇이냐에 따라 정적인 파일들만 반환할 수도 있고, javascript가 섞인 동적인 파일들을 반환할 수도 있다.

Ajax(Asynchronous javascript and XML)

  • Ajax는 자바스크립트를 이용하여 비동기적으로 서버와 브라우저가 데이터를 교환하는 통신 방식이다.
  • 서버에서 한번 페이지를 반환했을 때 거기에는 HTML와 같은 정적인 파일들 뿐만 아니라 javascript와 같이 동적인 파일들도 함께 반환한다.
  • 만약 페이지에서 일부만 지속적으로 갱신해야 한다면 굳이 모든 파일을 다시 반환할 필요가 없다.
  • 따라서 브라우저(웹클라이언트)는 Ajax request를 통해 동적인 부분을 요청하고 서버는 json을 통해 reload하는데 필요한 정보들을 반환 해준다.
동적크롤링

Ajax의 요청과 처리

  • 웹브라우저는 XMLHttpRequest 객체를 이용하여 Ajax요청을 보낸다.
  • 서버는 JSON형태로 요청온 정보만을 담아 순수한 텍스트로 구성된 데이터 문자열을 반환한다.
  • 이 문자열을 객체화하는 것을 역직렬화라고 하고 역직렬화를 위해 JSON.parse()를 이용한다.
동적크롤링1

크롤러

크롤러 : 인터넷에 있는 데이터를 자동 수집하는 프로그램

  • 웹 브라우저를 흉내내는 프로그램

정적 크롤링(크롬에서 페이지 소스보기가 가능할 때)

  • request: 웹 사이트에 접속, 데이터를 받아오는 역할
  • BeautifulSoup: 데이터를 HTML로 해석하는 역할

동적 크롤링

  • Ajax : 웹클라이언트에서 서버에 데이터를 요청하는 역할
  • JSON : 웹서버로부터 반환되는 데이터
  • JSON.parse() : 반환된 데이터를 사용할 수 있도록 객체화 해주는 역할

실습하기

  • 목표
    • 지속적으로 변하는 인기검색 10위까지의 순위 & 이름 & 현재시가 크롤링해보기
동적크롤링예제

코드

import requests
import json            #json import하기

#custom_header을 통해 아닌 것 처럼 위장하기
custom_header = {
    'referer' : 'http://http://finance.daum.net/quotes/A048410#home',
    'user-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'  }

#해당 접속 사이트가 아닌 원본데이터가 오는 url 추적. network에서 가지고 온다.
url = "http://finance.daum.net/api/search/ranks?limit=10"

req = requests.get(url, headers = custom_header)    #custom_header를 사용하지 않으면 접근 불가

if req.status_code == requests.codes.ok:    
    print("접속 성공")
    stock_data = json.loads(req.text)        #json에 반환된 데이터가 들어가 있다.
    for rank in stock_data['data']:         #stock_data는 'data' key값에 모든 정보가 들어가 있다.
        print(rank['rank'], rank['symbolCode'], rank['name'], rank['tradePrice'])

else:
    print("Error code")

접속 성공
1 A001000 신라섬유 2350
2 A068270 셀트리온 211500
3 A048410 현대바이오 12650
4 A005930 삼성전자 44650
5 A207940 삼성바이오로직스 338500
6 A020560 아시아나항공 6460
7 A002210 동성제약 20150
8 A007460 에이프로젠 KIC 4000
9 A066570 LG전자 77000
10 A000660 SK하이닉스 80200

+ Recent posts