일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- django widget
- form
- Algorithm
- 알고리즘
- DRF
- API
- 알고리즘 풀이
- javascript
- 파이썬
- django ORM
- CSS
- 장고
- Git
- AWS
- java
- Baekjoon
- HTML
- 알고리즘 연습
- c++
- js
- 백준
- PYTHON
- es6
- MAC
- web
- 파이썬 알고리즘
- django rest framework
- 알고리즘 문제
- react
- Django
- Today
- Total
수학과의 좌충우돌 프로그래밍
[Django] 좋아요 기능 구현하기 (ajax 사용 x) 본문
SNS 를 비롯해서 많은 사이트에는 좋아요, 하트 라고 불리는 기능이 있습니다. 아마 다들 뭔지 아실거라고 생각합니다. 이번에는 이 기능을 구현해보도록 하겠습니다.
그러기 위해서 부가적으로 구현되어야 할 것이 많습니다. 유저부터 시작해서 게시물 등 많지만 이 부분은 앞선 포스팅에도 있으므로 빠르게 넘어가도록 하겠습니다. 추가적으로 기능 구현에 주를 두고 있으므로 templates 의 디자인적인 부분은 아예 신경 쓰지 않았습니다.
좋아요 기능 구현
위에서 말했듯이 이번에 알아볼 중요 코드 외에 부가적인 코드가 많습니다. 그 부분 보다는 좋아요를 위한 코드 위주로 설명을 하도록 하겠습니다.
# like/models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
nickname = models.TextField(max_length=10)
like_posts = models.ManyToManyField('Post', blank=True, related_name='like_users')
def __str__(self):
return self.nickname
class Post(models.Model):
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
title = models.CharField(max_length=30)
content = models.TextField()
pub_date = models.DateTimeField(auto_now_add=True)
like_count = models.PositiveIntegerField(default=0)
def __str__(self):
return self.title
Profile
은 django의 User 를 OtO 으로 연결 시켜 확장한 모델이고 Post
는 게시물에 해당하는 모델입니다. 이 두 모델을 연결하여 좋아요를 구현할 수 있습니다. 유저 입장에서도 여러 게시물에 좋아요를 누를 수 있고 게시물 입장에서도 여러 유저한테 좋아요를 받을 수 있기 떄문에 MtM 로 연결이 되어야 할 것 입니다. Profile
의 필드에서 이를 찾을 수 있습니다.
like_posts = models.ManyToManyField('Post', blank=True, related_name='like_users')
Post
가 Profile
보다 아래 있기 때문에 문자열로서 관계를 지어주었습니다. 또한 유저가 처음 생길 때는 어떤 게시물 하고도 관계가 없기 때문에 blank=True
, 그리고 related_name
으로 반대쪽 모델에 접근 하기 위한 이름을 따로 지어주었습니다.
게시물의 좋아요 수는 Post
내에서 필드를 새롭게 만들어 주었습니다.
like_count = models.PositiveIntegerField(default=0)
처음에는 좋아요 수가 0개 이므로 default=0
을 설정해두었습니다.
<!-- templates/like/post_detail.html -->
<a href="{% url 'like:main' %}">뒤로 가기</a>
<div>제목</div>
<div>{{post.title}}</div>
<div>날짜</div>
<div>{{post.pub_date}}</div>
<div>내용</div>
<div>{{post.content}}</div>
<div>좋아요 수 : {{post.like_count}}</div>
<a href="{% url 'like:post_like_toggle' post.id %}">
{% if post in user.profile.like_posts.all %}
취소
{% else %}
좋아요
{% endif %}
</a>
가장 아래 a링크 있는 부분을 보도록 합시다. 해당 유저가 좋아요한 Post
를 모두 가지고 와서 현재 post 가 그 안에 있는 지 확인 합니다. 만약 있다고 하면 좋아요를 이미 누른 것이니 취소
를 보여주고, 그렇지 않으면 좋아요
를 보여주도록 합시다.
필요없는 부분은 전부 생략하고 좋아요
를 눌렀을 때 넘어갈 url 만 남겨주었습니다.
# config/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('like/', include('like.urls')),
]
# like/urls.py
from django.urls import path
from . import views
app_name = 'like'
urlpatterns = [
# 생략
path('post_like_toggle/<int:post_id>/', views.post_like_toggle, name="post_like_toggle"),
]
마찬가지로 좋아요
를 눌렀을 때 실행되는 함수만 남겨주었습니다.
# like/views.py
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.models import User
from django.contrib import auth
from .models import Profile, Post
from django.contrib.auth.decorators import login_required
@login_required
def post_like_toggle(request, post_id):
post = get_object_or_404(Post, id=post_id)
user = request.user
profile = Profile.objects.get(user=user)
check_like_post = profile.like_posts.filter(id=post_id)
if check_like_post.exists():
profile.like_posts.remove(post)
post.like_count -= 1
post.save()
else:
profile.like_posts.add(post)
post.like_count += 1
post.save()
return redirect('like:post_detail', post_id)
가장 위에 @login_required
를 통해서 login 을 했을 시에만 해당 함수에 접근이 가능하도록 했습니다. 우선 현재 로그인하고 있는 유저와 해당 게시물에 해당되는 profile
과 post
를 가져옵니다. 다음으로는 유저가 해당 게시물을 좋아요를 했는지 안했는지를 check_like_post
통해 확인해줍니다. 좋아요를 눌렀다면 check_like_post
가 존재할 것이고 좋아요를 누르지 않았다면 비어 있을 것 입니다. 이를 통해서 좋아요의 값을 증가 혹은 감소 시키고 저장시켜줍니다.
지금까지 간단하게 좋아요 기능에 대해서 알아보았습니다. 하지만 보통 좋아요 기능을 보면 버튼을 눌러도 화면이 redirect 되지 않습니다. 이를 위해 다음에는 ajax 를 통해서 좋아요 기능을 구현해보도록 하겠습니다.
'웹프로그래밍 > Django' 카테고리의 다른 글
[Django] json_script 를 이용한 효과적인 json parsing (1) | 2019.07.28 |
---|---|
[Django] django-debug-toolbar 설치하기 (0) | 2019.07.26 |
[Django] 관계를 표현하는 모델 필드, ForeignKey,OneToOneField,ManyToManyField (7) | 2019.07.20 |
[Django] 데이터베이스 조회, queryset (4) | 2019.07.18 |
[Django] admin 페이지 효율적으로 다루기 (1) | 2019.07.17 |