본문 바로가기
DEV/Web 개발

Web 개발 :: 파이썬 Django Rest Framework(11) _ 좋아요, 팔로우 기능

by 올커 2022. 11. 4.

DRF(Django Rest Framework)(11) _ 좋아요(Like), 팔로우(Follow) 기능

01. 좋아요(Like) 모델 생성하기

 - 좋아요 기능은 ManyToManyField로 생성한다. 기존에 있던 Article 모델에 추가해주도록 한다.

# articles/models.py

class Article(models.Model):
    ...
    likes = models.ManyToManyField(User, related_name='like_articles')

 - 여기서는 related_name을 지정해주어야 하는데, 이유는 related_name을 지정하지 않으면 기본적으로 지정되는 이름인 article_set이 할당되어야 할 필드가 두 개가 되기 때문이다.(기존에 user라는 ForeignKey로 만들어진 필드가 이미 있었다)


02. 좋아요(Like) 기능 구현하기

 - 좋아요 기능은 아래와 같이 코드를 작성했다. 해당되는 article을 가져오고, 만약 해당 article의 likes에 유저가 포함된다면, remove를 사용하여 '좋아요 취소'를, 포함되지 않는다면 add를 사용하여 '좋아요'를 실행한다.

# articles/views.py

class LikeView(APIView):
    def post(self, request, article_id):
        article = get_object_or_404(Article, id=article_id)
        if request.user in article.likes.all():
            article.likes.remove(request.user)
            return Response("좋아요 취소했습니다.", status=status.HTTP_200_OK)
        else:
            article.likes.add(request.user)
            return Response("좋아요 했습니다.", status=status.HTTP_200_OK)

 - 포스트맨으로 아래와 같이 headers를 넣어주고, url을 통해 request를 보내면 Send를 누를 때마다 follow/unfollow상태가 변경되는 것을 확인할 수 있다.

 


03. 팔로우(Follow) 모델 생성하기

 - 팔로우 모델은 users에 있는 User모델에서 필드를 추가해야 한다. 다대다 속성이므로 ManyToManyField로 생성한다.

 - followings라는 이름으로 필드를 생성했는데 옵션으로 symmetrical이 있다. 예를 들어 한 쪽에서 팔로우를 하면 양쪽 다 팔로우로 연결되는 속성인 경우 symmetrical=True, 한 쪽에서 팔로우를 해도 반대 쪽에서는 영향을 받지 않는 경우는 symmetrical=False로 설정해준다.

# users/models.py

...
class User(AbstractBaseUser):
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )
    followings = models.ManyToManyField('self', symmetrical=False, related_name="followers")
    ...

04. 팔로우(Follow) 기능 구현하기

 

 - 기능을 동작시킬 수 있도록 아래와 같이 url과 view를 지정해준다. FollowView는 상단의 좋아요 뷰와 거의 유사하다.

# users/urls.py

urlpatterns = [
    ...
    path('follow/<int:user_id>/', views.FollowView.as_view(), name='follow_view'),
]
# users/views.py

class FollowView(APIView):
    def post(self, request, user_id):
        you = get_object_or_404(User, id=user_id)
        me = request.user
        if me in you.followers.all():
            you.followers.remove(me)
            return Response("unfollow했습니다.", status=status.HTTP_200_OK)
        else:
            you.followers.add(me)
            return Response("follow했습니다.", status=status.HTTP_200_OK)

 - 마찬가지로 포스트맨으로 테스트해볼 수 있다.

 

반응형

댓글