티스토리 뷰

contents / models.py

class FollowRelation(BaseModel):
    follower = models.OneToOneField(User, related_name = 'follower', on_delete = models.CASCADE)
    followee = models.ManyToManyField(User, related_name = 'followee')

인스타그램의 가장 큰 포인트인 팔로우 언팔로우 기능을 구현한다.

평소에 follower : 나를 팔로우하는 사람  followee : 내가 팔로우하는 사람 으로 나눠서 의미를 구분했지만 여기서는 follower , followee 의 의미보다는 follow 자체의 의미에 집중해서 생각하는 것이 더 이해하기 쉽다.

 

         FollowRelation ( follower = a )

 

follower                                          followee

                                                   ┌────> b

      a ──── ( FOLLOW )├────> c

                                                   └────> d

 

 

 

 

         FollowRelation ( follower = f )

 

follower                                           followee

                                                   ┌────> a

      b ──── ( FOLLOW )├────> c

                                                   └────> d

 

 

위와 같은 관계도로 FollowRelation 객체가 형성된다.

이 관계망은 follower가 주체가 된다. 즉, follower가 로그인한 사용자가 되고 내가 팔로우하는 사람들의 목록이 followee가 된다.

 

한 명의 사용자는 하나의 관계망을 갖기 때문에 follower는 FollowRelation 객체와 OneToOneField 를 갖는다.

 

하나의 관계망은 여러 명의 followee를 갖고, 한 명의 followee는 여러 개의 관계망을 갖기 때문에 followee 는 FollowRelation 객체와 ManyToManyField 를 갖는다.

 

 

 

 

 

 

contents / admin.py

from django.contrib import admin
from contents.models import FollowRelation

class FollowRelationAdmin(admin.ModelAdmin):
    list_display = ('follower', )

admin.site.register(FollowRelation, FollowRelationAdmin)

 

 

 

 

 

 

 

apis / views.py / RelationCreateView

팔로우 API :  내가 (request.user) "팔로우" 버튼을 눌렀을 때 실행되는 API

 

첫 번째  (아이디 확인)

try:

내가 팔로우하려는 상대방(user_id)이 존재하는 값인지 확인한다.

except :

존재하지 않는 아이디인 경우에 오류메세지를 설정하고 되돌아간다.

 

두 번째 (내가(request.user) 주체가 되는 관계망 FollowRelation (follower = request.user)이 존재하는지 확인)

try :

FollowRelation (follower = request.user) 인 객체가 존재한다면 가져와서 relation에 저장 

except:

FollowRelation (follower = request.user) 가 없다면, follower = request.user 으로 하여 새로운 FollowRelation 객체 생성

 

세 번째 ( relation에 followee 추가 및 저장 )

try :

자기 자신은 팔로우하지 않도록 if 문 추가

내가 팔로우하려는 상대방(user_id)을 followee 필드에 추가하고 save()로 저장

except :

에러발생하면 오류 메세지 설정하고 되돌아간다.

 

@method_decorator(login_required, name = "dispatch")
class RelationCreateView(BaseView):
    def post(self, request):
        try:
            user_id = request.POST.get('id', '')
        except ValueError:
            return self.response(message = '잘못된 요청입니다.', status = 400)
        
        try:
            relation = FollowRelation.objects.get(follower = request.user)
        except FollowRelation.DoesNotExist:
            relation = FollowRelation.objects.create(follower = request.user)
        
        try:
            if user_id == request.user.id:
                raise IntegrityError
            relation.followee.add(user_id)
            relation.save()
        except IntegrityError:
            return self.response(message = '잘못된 요청입니다.', status = 400)
        
        return self.response({})

 

 

 

 

 

apis / views.py / RelationDeleteView

언팔로우 API :  내가 (request.user) "언팔로우" 버튼을 눌렀을 때 실행되는 API

 

첫 번째 ( 아이디 확인 )

try :

언팔로우 하려는 상대방(user_id)이 존재하는 아이디인지 확인

except :

존재하지 않는 경우, 에러메세지를 설정하고 되돌아간다.

 

두 번째( 나의 관계망이 존재하는지 )

try : follower = request.user 를 갖는 FollowRelation 객체가 있다면 가져와서 relation에 저장

except:

해당 객체가 없다면, 언팔로우할 것도 없으니 오류메세지를 지정하고 되돌아간다.

 

세 번째 ( 자기자신을 언팔로우하는건 아닌지 )

try :

언팔로우하려는 상대방이 나 자신이라면 IntegrityError 에러를 발생시킨다.

그게 아니라면, 언팔하려는 상대방(user_id)을 내 관계망의 followee 목록에서 제거하고 변경사항을 저장한다.

except :

나 자신을 언팔로우하여 IntegrityError가 발생하였으므로 오류 메세지를 지정하고 되돌아간다.

 

@method_decorator(login_required, name = 'dispatch')
class RelationDeleteView(BaseView):
    def post(self, request):
        try:
            user_id = request.POST.get('id', '')
        except ValueError:
            return self.response(message = "잘못된 요청입니다.", status = 400)

        try:
            relation = FollowRelation.objects.get(follower = request.user)
        except FollowRelation.DoesNotExist:
            return self.response(message = "잘못된 요청입니다.", status = 400)
        
        try:
            if user_id == request.user.id:
                raise IntegrityError
            relation.followee.remove(user_id)
            relation.save()
        except IntegrityError:
            return self.response(message = "잘못된 요청입니다.", status = 400)
        
        return self.response({})

 

 

 

댓글