데이터베이스의 관계에는 크게 세 가지가 있다.
이번에는 이러한 데이터베이스의 관계를 바탕으로 모델을 설계해 연결해보려고 한다.
SNS의 팔로우 - 팔로워 모델은 M : N 관계이고, 친구 속성은 사용자와 관련이 있으므로 UserModel 에 Follower 속성을 추가해준다.
# user/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.conf import settings # 장고가 알아서 setting 을 관리하게 해준다
# Create your models here.
class UserModel(AbstractUser):
class Meta:
db_table = "my_user"
bio = models.TextField(max_length=500, blank=True)
follow = models.ManyToManyField(settings.AUTH_USER_MODEL,related_name='followee') # M : N 관계를 명시해준다
모델을 만들어줬으니 이제 view.py 에서 백을 다듬자. (makemigrations 와 migrate 는 빼먹지 말고)
보여줘야할 기능은 총 세 개이다.
UserModel.objects.get() 을 통해 모든 유저를 가져온다. 단, 나의 정보를 제외해야 하므로 request.user 객체를 만들어 exclude 안에 넣어준다.
유저 정보를 모두 가져온 뒤에는 이를 {'user_list' : user_list} 형태로 만들어 프론트에 가져다준다.
@login_required
def user_view(request):
if request.method == 'GET':
user_list = UserModel.objects.all().exclude(username=request.user.username)
return render(request, 'user/user_list.html', {'user_list' : user_list})
버튼을 하나 만들어서 내가 그 사람의 followee 에 있는지 없는지에 따라 동작이 달라지도록 만들어주자. 만약 내가 프론트에서 받은 id의 followee 에 있다면 목록에서 지워지도록, 아니라면 추가되도록 만들어줄 것이다.
@login_required
def user_follow(request, id):
me = request.user # 접속한 본인
click_user = UserModel.objects.get(id=id) # 프론트에서 받은 id를 가진 user
if me in click_user.followee.all(): # 내가 클릭한 사람의 followee 에 있다면
click_user.followee.remove(request.user) # 나를 followee 에서 지운다
else:
click_user.followee.add(request.user) # 아니라면 나를 followee 에 더한다
return redirect('/user')
이렇게 백을 완성했으니 url을 만들어서 이어준다.
user/urls.py
urlpatterns = [
path('sign-up/', views.sign_up_view, name='sign-up'),
path('sign-in/', views.sign_in_view, name='sign-in'),
path('logout/', views.logout, name='logout'),
# 새로 추가한 부분
path('user/', views.user_view, name='user-list'), # 유저 리스트를 보여줄 화면
path('user/follow/<int:id>/', views.user_follow, name='user-follow') # 팔로우 취소 / 팔로우를 처리할 화면
]
이제 html 에서 데이터를 차례로 출력해주면 된다.
user/user_list.html
{% for ul in user_list %}
<div class="card">
<div class="card-body">
<h5 class="card-title">{{ ul.username }}</h5>
<h6 class="card-subtitle mb-2 text-muted">{{ ul.email }}</h6>
<p class="card-text">
{{ ul.bio }}
</p>
<p class="card-text">
팔로잉 {{ ul.follow.count }} 명 / 팔로워 {{ ul.followee.count }} 명
</p>
{% if ul in user.follow.all %}
<a href="/user/follow/{{ ul.id }}" class="card-link">[팔로우 취소]</a>
{% else %}
<a href="/user/follow/{{ ul.id }}" class="card-link">[팔로우]</a>
{% endif %}
</div>
</div>
<hr>
{% endfor %}
이후 base.html 의 네비게이션 바에
<li class="nav-item">
<a class="nav-link" href="/user"> 친구 <span class="sr-only"></span></a>
</li>
를 추가해주면 '친구' 를 누를 시 /user 화면으로 들어갈 수 있다.