여름의 서재
[Django] 좋아요 기능 구현하기_Like 본문
💡 Article과 Like는 무슨 관계일까?
: 한 게시글은 여러명에게 좋아요를 받을 수 있다. 또한 한 사람은 여러개의 게시글에 좋아요를 할 수 있다.
즉, Article과 Like_user는 N:N 관계를 가진다.
🔧 좋아요 기능 구현하기
1. articles/models.py
: ''유저는 게시글을 좋아한다.'' 여기서 table은 유저 테이블과 게시글 테이블이 사용되고 중간에 좋아요라는 행위가 중개테이블이 된다. 그래서 Article model에 user 테이블과 연결하는 like_users라는 이름의 manytomany 필드를 만들어야 한다.
이때, 꼭! related_name을 설정해줘야 한다. 그렇지 않으면 게시글을 작성한 유저를 나타내는 user 필드의 매니저와 충돌하게 된다. 둘다 user 테이블과 연결된 필드이기 때문에 manager가 user_set으로 표현된다. 그렇기 때문에 related_name을 써서 manager 충돌을 막아주자.
# articles/models.py
from django.db import models
from django.conf import settings
# Create your models here.
class Article(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
like_users = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='like_articles')
title = models.CharField(max_length=10)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
2. migrations & migrate
: DB 테이블을 변경해줬으니 migrate는 필수!!
python manage.py migrations
python manage.py migrate
3. articles/urls.py
: 좋아요를 추가하고 삭제할 때 쓰이는 url을 만들어준다.
from django.urls import path
from . import views
app_name = 'articles'
urlpatterns = [
# 생략
path('<int:article_pk>/likes/', views.likes, name='likes'),
]
4. articles.views.py
: 로그인이 된 유저일때만 좋아요 기능을 이용할 수 있다. 만약 요청이 들어왔을 때 현재 유저가 해당 게시글을 좋아요한 사람 중 한명이라면 좋아요를 취소하고, 아직 좋아요를 하지 않았다면 좋아요 한 사람에 현재 유저를 추가한다.
📌 article.like_users.filter(pk=request.user.pk).exists()
: 해당 게시글을 좋아요한 사람중에 pk가 현재 유저의 pk랑 같은 것이 존재하는지 하지 않는지를 판단한다.
request.user.like_articles.(pk=article_pk).exist() 라고 써도 같은 뜻이 된다.
@require_POST
def likes(request, article_pk):
if request.user.is_authenticated:
article = get_object_or_404(Article, pk=article_pk)
if article.like_users.filter(pk=request.user.pk).exists():
article.like_users.remove(request.user)
else:
article.like_users.add(request.user)
return redirect('articles:index')
return redirect('accouts:login')
5. templates
: 원하는 템플릿에 좋아요 버튼을 넣어준다. 현재 유저가 좋아요를 이미 한 상태라면 '좋아요 취소' 글씨를 출력하고, 아니라면 '좋아요' 글씨를 출력한다.
<div>
<form action="{% url 'articles:likes' article.pk %}" method='POST'>
{% csrf_token %}
{% if user in article.like_users.all %}
<input type="submit" value='좋아요 취소'>
{% else %}
<input type="submit" value='좋아요'>
{% endif %}
</form>
</div>
-> 글씨 대신 아이콘을 이용해서 빈 하트, 채워진 하트를 넣는 것도 가능하다!
<form action="{% url 'community:like' review.pk %}" method='POST'>
{% csrf_token %}
{% if review in user.like_reviews.all %}
<button class="btn btn-link text-danger">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-suit-heart-fill" viewBox="0 0 16 16">
<path d="M4 1c2.21 0 4 1.755 4 3.92C8 2.755 9.79 1 12 1s4 1.755 4 3.92c0 3.263-3.234 4.414-7.608 9.608a.513.513 0 0 1-.784 0C3.234 9.334 0 8.183 0 4.92 0 2.755 1.79 1 4 1z"/>
</svg>
</button>
{% else %}
<button class="btn btn-link text-danger">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-suit-heart" viewBox="0 0 16 16">
<path d="m8 6.236-.894-1.789c-.222-.443-.607-1.08-1.152-1.595C5.418 2.345 4.776 2 4 2 2.324 2 1 3.326 1 4.92c0 1.211.554 2.066 1.868 3.37.337.334.721.695 1.146 1.093C5.122 10.423 6.5 11.717 8 13.447c1.5-1.73 2.878-3.024 3.986-4.064.425-.398.81-.76 1.146-1.093C14.446 6.986 15 6.131 15 4.92 15 3.326 13.676 2 12 2c-.777 0-1.418.345-1.954.852-.545.515-.93 1.152-1.152 1.595L8 6.236zm.392 8.292a.513.513 0 0 1-.784 0c-1.601-1.902-3.05-3.262-4.243-4.381C1.3 8.208 0 6.989 0 4.92 0 2.755 1.79 1 4 1c1.6 0 2.719 1.05 3.404 2.008.26.365.458.716.596.992a7.55 7.55 0 0 1 .596-.992C9.281 2.049 10.4 1 12 1c2.21 0 4 1.755 4 3.92 0 2.069-1.3 3.288-3.365 5.227-1.193 1.12-2.642 2.48-4.243 4.38z"/>
</svg>
</button>
{% endif %}
</form>
'Skill > Django' 카테고리의 다른 글
[Django] 할 일 리스트 만들기_Todo (0) | 2021.10.25 |
---|---|
[Django] 팔로우 기능 구현하기_Follow (0) | 2021.10.24 |
[Django] 댓글 기능 구현하기_Comment (0) | 2021.10.22 |
[Django] 게시글에 User 정보 넣기_Article-User (0) | 2021.10.22 |
[Django] User model 커스텀하기 (0) | 2021.10.22 |