좋아요를 구현하기에 앞서 모델 M:N 관계를 숙지해야 한다.
다수 대 다수의 관계를 맺고 있는 좋아요는 M:N의 관계 이다.
쉽게 말해, 글 하나에 여러 개의 댓글이 구성하던 1:N 의 관계와 달리
여러 유저와 여러 개의 좋아요의 관계가 구성되기에 M:N 다수의 관계이다.
구현에 앞서, Blog, Comment, User 3개의 모델이 구성되어 있어야 한다.
먼저 model에 Like 모델을 다대다(ManyToManyField)를 활용한다
# project/blog/models.py
# M:N을 위한 속성
class User(models.Model):
...
likes = models.ManyToManyField(
User, # User 모델과 Blog 모델을 M:N 관계로 두겠다.
through = 'Like', # Like라는 중개 모델을 통해 M:N 관계를 맺는다.
through_fields = ('blog', 'user'), # Like에 blog 속성, user 속성을 추가하겠다.
related_name = 'likes' # 1:N 관계에서 blog와 연결된 comment를 가져올 때 comment_set으로 가져왔는데
# related_name을 설정하면 blog.like_set이 아니라 blog.likes로 like를 가져올 수 있다.
)
def like_count(self):
return self.likes.count() # 몇 개의 Likes와 연결되어 있는가를 보여주기 위한 메소드
class Like(models.Model):
# Blog의 through_fileds와 순서가 같아야 한다.
blog = models.ForeignKey(Blog, on_delete = models.CASCADE, null = True)
user = models.ForeignKey(User, on_delete = models.CASCADE, null = True)
다음, urls을 추가해준다.
# project/urls.py
urlpatterns =[
...
path('blog/like/<int:blog_id>', blog.views.post_like, name='post_like'), # like 처리를 위한 url
]
다음 template 수정하기
# project/blog/templates/blog/detail.html
...
<a href="{% url 'post_like' blog.id %}">{{message}}</a>
<br>{{blog.like_count}}명이 좋아합니다. <!-- Blog 모델에 정의한 like_count 메소드를 사용한다. -->
view에서 좋아요에 대한 조건문으로 처리하기
# project/blog/views.py
def detail
user = request.user
# 이미 좋아요를 눌렀다면 좋아요 취소, 안 눌렀으면 좋아요 버튼이 뜨도록 한다.
if blog_detail.likes.filter(id = user.id): # 로그인한 user가 현재 blog 객체에 좋아요를 눌렀다면
message = "좋아요 취소"
else:
message = "좋아요"
return render(request, 'blog/detail.html', {'blog':blog_detail, 'message':message})
def post_like(request, blog_id):
user = request.user # 로그인된 유저 객체를 가져온다.
blog = get_object_or_404(Blog, pk = blog_id) # 좋아요 버튼이 눌린 글을 가져온다.
# 이미 좋아요를 눌렀다면 좋아요 취소, 안 눌렀으면 좋아요 버튼이 뜨도록 한다.
if blog.likes.filter(id = user.id): # 로그인한 user가 현재 blog 객체에 좋아요를 눌렀다면
blog.likes.remove(user) # 해당 좋아요를 없앤다.
else:
blog.likes.add(user) # 아직 좋아요를 안 눌렀으면 좋아요를 추가한다.
return redirect('/blog/'+str(blog_id)) # 필요 정보들을 넘기고 detail 페이지로 넘어간다.
'Web Programming > Django' 카테고리의 다른 글
Static 추가하기 (0) | 2020.02.16 |
---|---|
Django 회원가입 이메일 인증(SMTP) (2) | 2020.02.09 |
백엔드_CRUD 실습 3 (0) | 2019.05.13 |
백엔드_CRUD 실습 2 (4) | 2019.05.10 |
백엔드_CRUD 실습 1 (0) | 2019.05.03 |