Django01 프로젝트 - 좋아요 기능 구현
2020년06월25일AJAX를 사용해서 좋아요 기능을 구현해 보았다.
models
좋아요는 여러 유저가 여러 포스트에 각각 누르는 형식이니 ManyToManyField로 구성해줘야 한다. 이후 개수를 카운트 하기 위해 아래에 PositiveIntegerField를 추가했다.
like_users = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='like_boards')
like_count = models.PositiveIntegerField(default=0)
Ajax 없이 구현해보기
한 번 Ajax없이 구성도 해보았다.
urls
path('<int:pk>/like/', views.like, name='like'),
views
post.like_users를 통해 해당 게시물에 유저가 있는지 확인하고, 있으면 제거하고 없으면 넣어주는 형식이다.
def like(request, pk):
post = get_object_or_404(Userboard, pk=pk)
if request.user in post.like_users.all():
post.like_users.remove(request.user)
else:
post.like_users.add(request.user)
return redirect(store.get_absolute_url())
Ajax로 구현해보기
먼저 jQuery를 이용해서 스크립트를 만들어 준다. 선택자는 button태그에 like가 포함된 엘레먼트들을 고르게 해줬다. 이렇게 사용한 이유는, 아래 코드를 js파일로 저장해서 로드해서 사용하기 위해서다. 현재 내 프로젝트는 가게와 게시판 기능이 있는데, 각각 사용하기 위해서이다. 이렇게 하면 js파일에선 템플릿 변수를 사용못하기 때문에 script태그 안에 내가 사용할 변수들을 MyGlobal에 저장해 주었다.
JavaScript
<script>
var MyGlobal = {
url: "{% url 'board:like' %}",
}
</script>
$("[class*=like]").click(function () {
var pk = $(this).attr('post-id')
$.ajax({
type: "GET",
url: MyGlobal.url,
data: {'pk': pk},
dataType: "json",
success: function (response) {
$("#count-" + pk).html(response.like_count + "개");
var users = $("#like-user-" + pk).text();
if (response.message) {
$('#like-heart-'+pk).removeClass('far fa-heart').addClass('fas fa-heart');
} else {
$('#like-heart-'+pk).removeClass('fas fa-heart').addClass('far fa-heart');
}
},
error: function (request, status, error) {
alert("로그인이 필요합니다.")
window.location.replace("/accounts/login/")
}
})
});
views
json 형태로 반환해주기 위해 아래의 두 모듈을 import 해준다.
from django.http import HttpResponse
import json
@login_required
def like(request):
pk = request.GET.get('pk', None)
board = get_object_or_404(UserBoard, pk=pk)
if request.user in board.like_users.all():
board.like_users.remove(request.user)
board.like_count -= 1
board.save()
message = False
else:
board.like_users.add(request.user)
board.like_count += 1
board.save()
message = True
context = {
'like_count': board.like_users.count(),
'message': message,
}
return HttpResponse(json.dumps(context), content_type="application/json")
html
<a href="{% url 'store:like' store.pk %}">
{% if user in store.like_users.all %}
<a href="{% url 'store:like' store.pk %}"><i class="fas fa-heart"></i></a>
{% else %}
<a href="{% url 'store:like' store.pk %}"><i class="far fa-heart"></i></a>
{% endif %}
<p class="card-text">
{{ store.like_users.count }} 명이 좋아합니다.
</p>
</a>