여름의 서재

[Django] 팔로우 기능 구현하기_Follow 본문

Skill/Django

[Django] 팔로우 기능 구현하기_Follow

엉아_ 2021. 10. 24. 15:48
728x90

💡 User와 Follow는 무슨 관계일까?

: 한 사람이 여러 사람을 팔로우할 수 있고, 한 사람이 여러 사람에게 팔로우를 당할 수 있다.

즉, user 테이블끼리의 N:N 관계가 된다.

 

🔧 좋아요 기능 구현하기

1. accounts/models.py

: 자기가 자기자신을 다시 참조하는 것이기 때문에 self 라는 인자를 준다. symmetrical은 대칭을 할지 말지를 결정하는 건데 여기서 이 옵션에 True를 주면 한 사람이 어떤 사람을 팔로우하면 저절로 맞팔이 되게 된다. 그렇기 때문에 여기서는 False로 줄 것이다.

 

from django.db import models
from django.contrib.auth.models import AbstractUser

# Create your models here.
class User(AbstractUser):
    followings = models.ManyToManyField('self', symmetrical=False, related_name='followers')

 

2. migrations & migrate

: DB 테이블을 변경해줬으니 migrate는 필수!!

python manage.py migrations
python manage.py migrate

 

3. accounts/urls.py

: 팔로우를 하고 취소할 때 쓰이는 url을 만들어준다.

from django.urls import path
from . import views


app_name = 'accounts'
urlpatterns = [
	# 생략
    path('<int:user_pk>/follow/', views.follow, name='follow'),
]

 

4. accounts.views.py

: 로그인이 된 유저일때만 팔로우 기능을 이용할 수 있다. 만약 요청이 들어왔을 때 현재 유저가 해당 유저를 팔로우한 사람 중 한명이라면 팔로우를 취소하고, 아직 팔로우를 하지 않았다면 팔로우 한 사람에 현재 유저를 추가한다.

 

📌 if person != request.user

: 자기자신을 팔로우하면 안 되기 때문에 현재 유저가 해당 유저가 아닐때 팔로우 기능이 실행되도록 해주었다.

 

def follow(request, user_pk):
    if request.user.is_authenticated:
        person = get_object_or_404(get_user_model(), pk=user_pk)
        if person != request.user:
            # if request.user.followings.filter(pk=user_pk).exists():
            if person.followers.filter(pk=request.user.pk).exists():
                person.followers.remove(request.user)
            else:
                person.followers.add(request.user)
        return redirect('accounts:profile', person.username)
    return redirect('accounts:login')

 

5. templates

: 현재 유저가 해당 유저를 팔로우 한 상태가 아닐때는 '팔로우' 버튼을 출력하고, 팔로우를 이미 한 상태일때는 '팔로우 취소' 버튼을 출력한다.

<div>
  <div>
    팔로잉 : {{ person.followings.all|length }} / 팔로워 : {{ person.followers.all|length }}
  </div>

  {% if user != person %}
    <div>
      <form action="{% url 'accounts:follow' person.pk%}" method='POST'>
        {% csrf_token %}
        {% if user in person.followers.all %}
          <input type="submit" value='팔로우 취소'>
        {% else %}
          <input type="submit" value='팔로우'>
        {% endif %}
      </form>
    </div>  
  {% endif %}
</div>
Comments