▶️ Django
[▶️Back-end] 메인 페이지에 좋아요, 싫어요 버튼 기능 구현 1차
Like 모델을 추가했어요.
그와 관련된 views.py, urls.py도 추가했어요.
Like 모델 구현 시작!
⚙️ articles/models.py
더보기
더보기
# articles/models.py
# Like 모델
class Like(models.Model):
"""
유저가 게시글에 좋아요/싫어요 누른 정보를 저장하는 모델이에요.
"""
user = models.ForeignKey(
User, on_delete=models.CASCADE, related_name="user_likes"
)
article = models.ForeignKey(
Article, on_delete=models.CASCADE, related_name="article_likes"
)
like_type = models.CharField(
max_length=10, choices=(("Like", "like"), ("Dislike", "dislike"))
)
# 유저-게시글 조합은 유일해야 함. 중복 좋아요 방지
class Meta :
unique_together = ("user", "article")
def __str__(self):
return f"{self.user.username} - {self.article.title} - {self.like_type}"
⚙️ articles/urls.py
더보기
더보기
from django.urls import path
from django.conf.urls.static import static
from django.conf import settings
from .views import ArticleList, ArticleLike
app_name = "articles"
urlpatterns = [
path("", ArticleList.as_view(), name="main"), # 게시물 목록
# article_id와 like_type을 URL 피라미터로 받음 ⬇️
path("articles/<int:id>/like/<str:like_type>/", ArticleLike.as_view(), name="articlelike"),
]
⚙️ articles/views.py
더보기
더보기
from django.shortcuts import render, get_object_or_404 , redirect
from django.views import View
from django.contrib.auth.mixins import LoginRequiredMixin # 로그인한 사용자만 특정 view에 접근할 수 있음
from .models import Article, Like
from django.http import HttpResponseForbidden # error 403(서버에 요청은 갔지만, 권한 때문에 요청 거절)
...
# 좋아요 게시물
class ArticleLike(LoginRequiredMixin, View): # 로그인 필수 기능 추가
login_url = "/users/login/" # 로그인 되지 않았으면 로그인 url로 보냄
def post(self, request,id, like_type): # 이렇게 적으면 article_id를 URL에서 받음
article = get_object_or_404(Article, pk=id)
user = request.user # 현재 로그인한 유저
# like_type 유효성 검사 (모델 choices 사용)
valid_like_types = [choice[0] for choice in Like.like_type.field.choices] #Like 모델 필드 LikeType의 choices 속성 사용
if like_type not in valid_like_types:
return HttpResponseForbidden("잘못된 요청입니다.")
# 이미 좋아요/싫어요를 누른 경우 (예 : 취소 또는 변경)
try:
existing_like = Like.objects.get(user=user, article=article)
if existing_like.like_type == like_type:
# 같은 종류의 좋아요/싫어요를 다시 누른 경우 (예: 취소)
existing_like.delete()
if like_type == "like":
article.like_count = max(0, article.like_count - 1) # 최댓값 == 0, 게시물의 좋아요 개수에서 -1
else:
article.dislike_count = max(0, article.dislike_count - 1) # 최댓값 == 0, like가 아니라 dislike일 경우
else: # 예) 좋아요 -> 싫어요, 싫어요 -> 좋아요
# 다른 종류의 좋아요/싫어요로 변경
if like_type == "like":
article.like_count += 1
article.dislike_count = max(0, article.dislike_count - 1) # 싫어요 -> 좋아요로 간 경우임
else:
article.like_count = max(0, article.like_count - 1)
article.dislike_count += 1
existing_like.like_type = like_type
existing_like.save() # 좋아요 또는 싫어요 관련 정보 저장.
article.save() # 해당 게시물 저장
except Like.DoesNotExist:
# 좋아요/싫어요를 처음 누른 경우
Like.objects.create(user=user, article=article, like_type=like_type)
if like_type == "like":
article.like_count += 1
else:
article.dislike_count += 1
article.save()
return redirect("articles:main") # 상세 페이지로 리다이렉션
오류 수정
코드 구현을 끝낸 후 장고 서버에 들어가 봤는데 오류가 터졌어요,, 네,,
⚙️ articles/models.py
더보기
더보기
# articles/models.py
# Like 모델
class Like(models.Model):
"""
유저가 게시글에 좋아요/싫어요 누른 정보를 저장하는 모델이에요.
"""
user = models.ForeignKey(
User, on_delete=models.CASCADE, related_name="user_likes"
)
article = models.ForeignKey(
Article, on_delete=models.CASCADE, related_name="article_likes"
)
like_type = models.CharField(
max_length=10, choices=(("❤️", "like"), ("🤨", "dislike"))
)
# 유저-게시글 조합은 유일해야 함. 중복 좋아요 방지
class Meta :
unique_together = ("user", "article")
def __str__(self):
return f"{self.user.username} - {self.article.title} - {self.like_type}"
<수정한 내용>
like_type = models.CharField(
max_length=10, choices=(("❤️", "like"), ("🤨", "dislike"))
)
choices 부분을 수정했어요.
choices는
- 튜플로 구성돼 있어요.
- (A, B)
- A : DB에 저장될 값
- B : 사람이 읽을 수 있는 라벨
이렇게 구성돼 있어요.
❤️를 누르면 like가 되는 것이고, 🤨를 누르면 dislike가 돼요.
⚙️ articles/views.py
<수정 내용>
if like_type == "like":
이 부분을
if like_type == "❤":
이렇게 바꾸어주었어요.
왜냐면 models.py에 choices를 ❤️와 🤨로 바꾸었기 때문이에요!
<전체 views.py>
더보기
더보기
from django.shortcuts import render, get_object_or_404 , redirect
from django.views import View
from django.contrib.auth.mixins import LoginRequiredMixin # 로그인한 사용자만 특정 view에 접근할 수 있음
from .models import Article, Like
from django.http import HttpResponseForbidden # error 403(서버에 요청은 갔지만, 권한 때문에 요청 거절)
# 좋아요 게시물
class ArticleLike(LoginRequiredMixin, View): # 로그인 필수 기능 추가
login_url = "/users/login/" # 로그인 되지 않았으면 로그인 url로 보냄
def post(self, request,id, like_type): # 이렇게 적으면 article_id를 URL에서 받음
article = get_object_or_404(Article, pk=id)
user = request.user # 현재 로그인한 유저
# like_type 유효성 검사 (모델 choices 사용)
valid_like_types = [choice[0] for choice in Like.like_type.field.choices] #Like 모델 필드 LikeType의 choices 속성 사용
if like_type not in valid_like_types:
return HttpResponseForbidden("잘못된 요청입니다.")
# 이미 좋아요/싫어요를 누른 경우 (예 : 취소 또는 변경)
try:
existing_like = Like.objects.get(user=user, article=article)
if existing_like.like_type == like_type:
# 같은 종류의 좋아요/싫어요를 다시 누른 경우 (예: 취소)
existing_like.delete()
if like_type == "❤️":
article.like_count = max(0, article.like_count - 1) # 최댓값 == 0, 게시물의 좋아요 개수에서 -1
else:
article.dislike_count = max(0, article.dislike_count - 1) # 최댓값 == 0, like가 아니라 dislike일 경우
else: # 예) 좋아요 -> 싫어요, 싫어요 -> 좋아요
# 다른 종류의 좋아요/싫어요로 변경
if like_type == "❤️":
article.like_count += 1
article.dislike_count = max(0, article.dislike_count - 1) # 싫어요 -> 좋아요로 간 경우임
else:
article.like_count = max(0, article.like_count - 1)
article.dislike_count += 1
existing_like.like_type = like_type
existing_like.save() # 좋아요 또는 싫어요 관련 정보 저장.
article.save() # 해당 게시물 저장
except Like.DoesNotExist:
# 좋아요/싫어요를 처음 누른 경우
Like.objects.create(user=user, article=article, like_type=like_type)
if like_type == "❤️":
article.like_count += 1
else:
article.dislike_count += 1
article.save()
return redirect("articles:main") # 상세 페이지로 리다이렉션
'👥 최종 팀 프로젝트(250227~250331) > 구현 과정 ▶️' 카테고리의 다른 글
[▶️Front-end] 메인 페이지에 좋아요, 싫어요 버튼 기능 구현 (0) | 2025.03.06 |
---|---|
[▶️Back-end] 메인 페이지에 좋아요, 싫어요 버튼 기능 구현 3차 完 (0) | 2025.03.06 |
[▶️Back-end] 메인 페이지에 좋아요, 싫어요 버튼 기능 구현 1차 (1) | 2025.03.04 |
[▶️Front-end] Bootstrap으로 화면 구성(회원 가입, 로그인, 로그아웃) (0) | 2025.03.03 |
[▶️Back-end] Auth 기능 구현하기(회원 가입, 로그인, 로그아웃) 2차 完 (0) | 2025.03.03 |