Ajax - ajax 이용한 실시간 댓글 생성 및 좋아요 개수 표시
- 이번 포스트에서는 ajax를 이용하여 댓글 작성 및 특정 댓글의 좋아요 개수를 표시하는 방법에 대해 알아볼 것이다.
ajax를 이용한 실시간 댓글 작성 및 좋아요 개수 표시
1. 서버에 ajax 요청
경로 : post > templates > post > post_detail.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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77{% block content %}
...
<form action="{% url 'post:comment_create' object.id %}" method="post" id="comment_form">
{% csrf_token %}
<input type="hidden" name="is_ajax" value="">
<div class="row" style="width:590px; padding-right:10px;">
<div id="comment_write" class="col-8" style="padding:0 0 0 5px;">{{comment_form.text}}</div>
<div class="col">
<input type="submit" value="댓글 입력" class="btn btn-outline-primary form-control">
</div>
</div>
</form>
<!-- 유저들 댓글 조회 부분 -->
<div id="comment_list">
{% include 'post/comment_list.html' %}
</div>
...
{% endblock %}
{% block extra_script %}
<!-- 댓글 폼 작성 시 -->
$("#comment_form").submit(function(e){
e.preventDefault();
<!-- name이 is_ajax인 input type의 value를 1로 설정 -->
$('input[name="is_ajax"]').val("1");
<!-- 해당 input의 action 태그에 있는 경로를 url로 저장 -->
url = $(this).attr('action');
<!-- 해당 input에 저장된 데이터를 하나로 모아(serialize) params 변수에 저장 -->
params = $(this).serialize();
$.ajax({
url: url,
method: "POST",
data: params,
}).done(function(data){
<!-- 댓글 조회 부분에 data.html 추가 -->
$('#comment_list').prepend(data.html);
<!-- input 태그의 name이 is_ajax인 value값 초기화 -->
$('input[name="is_ajax"]').val("");
<!-- 댓글 입력부분의 문자열 초기화 -->
$('#id_text').val("");
});
});
<!-- 댓글 좋아요 버튼 클릭시 -->
$(".btn-comment-like").click(function(e){
e.preventDefault();
<!-- 댓글 좋아요 버튼 클릭한 객체를 selected_object 변수에 할당 -->
selected_object = $(e.currentTarget);
<!-- selected_object의 href 태그에 있는 경로를 url 변수로 저장 -->
url = selected_object.attr('href')
console.log(url);
$.ajax({
url:url,
method:"POST",
data:{
'csrfmiddlewaretoken':'{{csrf_token}}',
'is_ajax':true,
},
}).done(function(data){
if(data.works){
<!-- 서버에서 수신한 data key값으로 works가 있는 경우 -->
<!-- selected_object의 html부분의 whitespace 제거한 데이터를 str_comment_like 변수로 저장 -->
str_comment_like = selected_object.html().trim();
<!-- str_comment_like에서 숫자를 match한 결과가 null값이면 selected_object에 html 형식으로 '좋아요 1개' 표시 -->
if(str_comment_like.match(/[0-9]+/g)==null){
selected_object.html(" 좋아요 1개")
}
<!-- str_comment_like에서 숫자를 match한 결과가 null이 아닌 경우 -->
else{
<!-- str_comment_like에서 숫자로만 되어 있는 문자열을 int_comment_like 변수에 저장 및 int type으로 변경 후, 개수 1 증대한 값을 comment_like 변수에 저장 -->
int_comment_like = str_comment_like.match(/[0-9]+/g);
comment_like = parseInt(int_comment_like[0]) + 1;
<!-- selected_object.html에 좋아요 개수 표시 -->
selected_object.html(" 좋아요 "+comment_like+"개")
}
}
});
});경로 : post > templates > post > comment_list.html
1
2
3{% for comment in comments %}
{% include 'post/comment_single.html' %}
{% endfor %}경로 : post > templates > post > comment_single.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14<div style="margin-bottom: 20px;">
<div class="img-profile" style="background-image:url({{comment.author.profile.url}})"></div>
<div style="float:left; height:100%; width:550px; line-height:100%;">
<div style="display:inline-block; vertical-align:middle; line-height:normal;">
<p style="padding:10px; border-radius:25px; background-color:rgb(237,237,237); display:inline-block; margin:0">
<a style="color:rgb(37,71,194); font-weight:bold;" href="#">{{comment.author.last_name}}{{comment.author.first_name}}</a> {{comment.text}}
</p>
<a class="btn-comment-like" href="{% url 'post:comment_like' comment.id %}"> 좋아요 {% if comment.like %}{{comment.like}}개{% endif %}</a>
<a class="btn-comment-update-delete" href="{% url 'post:comment_update' comment.id %}"> 수정</a>
<a class="btn-comment-update-delete" href="{% url 'post:comment_delete' comment.id %}">삭제</a>
</div>
</div>
<div style="clear:both;"></div>
</div>
2. 서버에서 ajax로 데이터 송신
- 경로 : post > views.py
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
37def comment_create(request, post_id):
# ajax 요청에서 is_ajax 데이터 수신
is_ajax = request.POST.get('is_ajax')
# 특정 post_id를 pk 값으로 갖는 post 객체를 post 변수로 저장
post = Post.objects.get(pk=post_id)
# 댓글폼에 입력한 데이터를 POST 형식으로 요청한 댓글폼을 comment_form 변수로 저장
comment_form = CommentForm(request.POST)
# 요청한 유저를 comment_form의 작성자로 저장
comment_form.instance.author_id = request.user.id
comment_form.instance.post_id = post_id
# comment_form이 검증 완료되었다면, comment_form 데이터 저장
if comment_form.is_valid():
comment = comment_form.save()
# ajax 요청 데이터에 is_ajax 가 있다면,
if is_ajax:
# comment_single.html에 있는 문자열을 렌더링 및 comment를 context data로 설정하여 html 변수에 저장
html = render_to_string('post/comment_single.html',{'comment':comment})
# JsonResponse로 html를 ajax 요청한 페이지에 송신
return JsonResponse({'html':html})
return redirect(post)
def comment_like(request, comment_id):
# ajax 요청에서 is_ajax 데이터 수신
is_ajax = request.POST.get("is_ajax")
# ajax 요청한 데이터에 is_ajax 있는 경우
if is_ajax:
# 특정 comment_id를 pk값으로 갖고 있는 댓글을 comment로 설정
comment = Comment.objects.get(pk=comment_id)
# comment.like에 +1한 값을 다시 comment.like로 저장
comment.like = comment.like + 1
# 해당 comment 객체 저장
comment.save()
# JsonResponse로 'works'를 True로 설정하여 ajax 요청한 페이지에 송신
return JsonResponse({'works':True})
# ajax 요청한 데이터에 is_ajax 없는 경우, 현재 url로 이동
return redirect('/')
Posted