Django Assignment 1 | Westagram 9)

김기현·2022년 2월 24일
0
post-thumbnail

[Mission 10] 다른 계정 'follow' 기능 구현

미션

  • User app 활용
    follow와 following은 유저들 사이에서 일어나는 기능이기 때문에 users app을 활용합니다.
  • Follow Model 생성
    팔로우를 하기 위해서는 팔로우 당하는 유저와 팔로우 하는 유저가 포함되어야 합니다.
    팔로우 당하는 유저와 팔로우 하는 유저 모두 Foreign Key를 이용하여 이미 가입된 사람과 연결합니다.
    이때 하나의 클래스 내에서, 같은 객체를 참조할 경우 발생하는 에러를 확인하시고, related_name 속성을 사용해 해결합니다.

  • Follow View 생성
    FollowView 클래스를 생성합니다.
    팔로우를 할 때에는 post메소드를 사용합니다.
    이미 팔로우한 유저를 해당 유저가 또 팔로우했을 경우도 대비합니다.

  • Urls.py 작성
    클라이언트의 요청을 받아서 팔로우 뷰를 호출할 수 있도록 urls.py 를 작성해 주세요.

수정 사항들 내용

  • 모델링
# users/models
class Follow(models.Model):
    followuser    = models.ForeignKey('User', related_name='followings', on_delete=models.CASCADE) 
    followeduser  =  models.ForeignKey('User', related_name='followed', on_delete=models.CASCADE) 
    
    class Meta:
        db_table = "follows"

만약 여기서 related_name이 같거나, 혹은 없다면 다음의 에러를 생성합니다.

  • related_name이 없을 경우
    following_userfollowed_user이 충돌을 일으킵니다.

  • related_name이 같을 경우
    following_userfollowed_user이 충돌을 일으킵니다.

  • url

 # users/url
from django.urls import path, include
from users.views import SignUpView, LoginView, FollowView

urlpatterns = [
    path("/signup", SignUpView.as_view()),
    path("/login", LoginView.as_view()),
    path("/follow", FollowView.as_view()),
]

뷰 연결을 잘합시다!!!(뷰 연결 잘못해놓고선 몇 시간 의미없는 삽질.... 키 에러의 늪에서 빠져나옵시다!!)

  • views
 # users/views
 # 섹션 1
class FollowView(View):					
    def post(self, request):
        data = json.loads(request.body)
        token   = request.headers.get("Authorization")
        payload = jwt.decode(token, SECRET_KEY, ALGORITHM)
        
        try:
            followeduser = data['followeduser_id']
            followuser = payload['user_id']
# 섹션 2
            try:							
                get_follow    = Follow.objects.get(followeduser_id = followeduser)
                get_following = Follow.objects.get(followuser_id = followuser)

                if get_follow.id == get_following.id:
                    get_follow.delete()
                    return JsonResponse({"message" : "delete LIKE SUCCESS"}, status = 201)
            except:
                pass
# 섹션 3										
            if followeduser == '' and followuser == '':
                return JsonResponse({"message" : "Please type id"}, status = 400)

            if Follow.objects.filter(followuser_id = followuser, followeduser_id = followeduser).exists():
                return JsonResponse({'message' : 'You have already followed'},status=401) 
# 섹션 4      									
            else:						
                Follow.objects.create(
                    followuser_id   = payload['user_id'],
                    followeduser_id = followeduser,
                )
                return JsonResponse({"message" : "SUCCESS"}, status = 201)       


        except KeyError:
            return JsonResponse({'message' : 'KEY_ERROR'},status=400)
  • 섹션 1 설명
    request.headers.get() 은 GET 요청이 접근할 수 있는 키와 밸류값을 사용합니다. 그리고 data = json.loads(request.body)는 headers 에서 get 을 받겠다는 의미로, get 메서드로 받는것이 딕셔너리로 되어있고 key 가 Authorization인 것을 받겠다는 얘기입니다. 그리고 토큰으로 유저를 해독하기 하는 과정을 payload로 담습니다.

  • 섹션 2 설명
    만약 followeduser_id가 followeduser인 경우를 get_follow로 지정하고, followuser_id가 followuser인 경우를 get_following에 넣습니다. 그 후 해당 변수의 id가 같다면 한번 더 좋아요를 누른 경우이므로 delete하는 과정을 거칩니다.

  • 섹션 3 설명
    만약 followeduser 또는 followuser가 비어있다면 id를 입력하라고 합니다. 그리고 followuser_id = followuser, followeduser_id = followeduser인 경우는 이미 팔로우가 되어있는 상태이므로 팔로우 중이라는 메시지를 던집니다. (팔로우 하는 유저가 똑같고 팔로우 당하는 유저가 같다면)

  • 섹션 4 설명
    모든 조건을 거치면 팔로워와 팔로우 기능을 하도록 합니다. 이 때 팔로우하는 유저는 토큰을 해독하는 과정을 거치도록 해야 하며, 팔로워하려는 유저의 id를 입력하도록 합니다.

Tada~!

헤매었던 에러(인스턴스 에러)

ValueError : Cannot assign "XXXX" must be a "XX" instance라고 에러를 내뱉습니다.
db에 접근하기 위해선 User 인스턴스로 맞춰주어야 하는데 Follow.followuser, Follow.followeduser의 id를 넣는 것을 의도하였기 때문에 Follow.followuser_id가 되어야 합니다. 결론적으론 User 인스턴스로 되려면 다음의 코드로 바꿔주어야 합니다.

followuser_id = payload['user_id']
followeduser_id = followeduser

이 페이지를 참고하여 디버깅을 하였습니다.

profile
피자, 코드, 커피를 사랑하는 피코커

0개의 댓글