Django 05

·2023년 9월 1일
0

파이썬

목록 보기
9/18

데이터베이스의 관계

데이터베이스의 관계에는 크게 세 가지가 있다.

  • 일대일 관계(1 : 1)
    대한민국 국민 - 주민등록번호
    음료 이름 - 음료 사진
    국가 - 국가의 수도
    과 같이 말 그대로 하나 당 하나가 매치되는 관계이다.
  • 일대다 관계(1 : N)
    여자 - 사람
    과 같이 하나 당 여러 개가 매치되는 관계이다.
  • 다대다 관계(M : N)
    가장 흔한 관계이다. 여러 개가 서로 매치되는 관계이다.

이번에는 이러한 데이터베이스의 관계를 바탕으로 모델을 설계해 연결해보려고 한다.

팔로우 - 팔로워 모델

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 관계를 명시해준다
  • related name : 자신을 참조해야할 필요가 있을 때 넣어주는 속성, follow 와 followee 는 같은 UserModel class 를 참조하고 있으니 필수적으로 넣어줘야 한다.
    이 코드에서는 followee 를 통해 팔로우 관계에 있는 UserModel 에 접근하게 해준다.
    참고

모델을 만들어줬으니 이제 view.py 에서 백을 다듬자. (makemigrations 와 migrate 는 빼먹지 말고)

보여줘야할 기능은 총 세 개이다.

  1. 나를 제외한 유저 보여주기, 이때 팔로우에 등록된 유저들을 내가 팔로우하고 있으면 팔로우 취소로, 팔로우하지 않고 있으면 팔로우 버튼으로 보이게 하기
  2. 팔로우 취소를 누르면 내 팔로우 목록 테이블에서 그 사람을 삭제하기
  3. 팔로우를 누르며녀 내 팔로우 목록에 그 사람을 추가하기

나를 제외한 유저 목록 보여주기

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 %}
  • views.py 의 user_view 를 통해 받은 user_list 의 정보를 차례차례 출력한다. 이때 follow 속성과 followee 속성을 각각 count 하여 화면에 출력해준다.
  • 이때 표시되는 user 가 접속한 나(user) 의 팔로우 목록에 있으면 팔로우 취소 버튼을 보여주고, 그렇지 않으면 팔로우 버튼을 보여준다.

이후 base.html 의 네비게이션 바에

<li class="nav-item">
    <a class="nav-link" href="/user"> 친구 <span class="sr-only"></span></a>
</li>

를 추가해주면 '친구' 를 누를 시 /user 화면으로 들어갈 수 있다.

  • 화면을 실행하기 전 /admin 에서 미리 user 정보와 follow 목록을 만들어 주었다.
profile
공부 중

0개의 댓글