django 4-7 ManyToMany 팔로우

Grace Goh·2022년 10월 12일
0

Django

목록 보기
24/32

view 만들기
follow는 user 관련 기능

user/views.py

# 에 붙여넣기

@login_required
def user_view(request):
    if request.method == 'GET':
        # 사용자 불러오기, exclude와 request.user.username 사용해서 '로그인한 사용자'를 제외하기
        user_list = UserModel.objects.all().exclude(username=request.user.username)
        return render(request, 'user/user_list.html', {'user_list': user_list})

get으로 요청이 들어오면 어떤 것을 보여주겠다는 의미.

user_view 화면은 전체 사용자 리스트를 가져와서 user_list로 출력해준다. (마찬가지로 로그인이 필요한 화면)

  • render(, '.html', {})
    위 html을 보여줄 건데 user_list와 같이 보여주겠다.

  • 변수 user_list는 UserModel.objects.all()
    .exclude는 해당 데이터에서 request.user.username을 제외한다.

    • request.user : 나(로그인한 사용자). 이 사용자의 .username이 검색 조건.
  • 친구리스트, 사용자리스트를 보는데 굳이 내가 나를 볼 필요는 없다. 내가 나를 follow할 이유도 없다.
    따라서 나를 제외한 사용자 리스트를 가져온다.

@login_required
def user_follow(request, id):
    me = request.user # 로그인한 사용자
    click_user = UserModel.objects.get(id=id)
    if me in click_user.followee.all():
        click_user.followee.remove(request.user)
    else:
        click_user.followee.add(request.user)
    return redirect('/user')

me = request.user

click_user 내가 누른 사람(눌림 당한 사용자)의 모델을 가져와서, 그 사람을 follow하는 모든 사람을 가져온다.
follow 또는 unfollow 하기 위해.

(UserModel에서 나왔기 때문에 사용자 중 한 명이다.
그 안에서 followee.all()을 가져온다.)

if 그 사람을 follow하는 모든 사람 중 내가 있다면, 이미 팔로우 중이므로 목록에서 remove한다. (다시 한 번 요청click했을 때는 follow 취소할 수 있게 해준다.)

else 만약 그 안에 없다면, 그 사람을 follow하게 해준다.

views를 작성했으니 위 views와 연결되는 urls를 작성한다.

user/urls.py

from django.urls import path
from . import views


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'), 
    # user/ 경로 화면에서 user_view를 보여준다.
    path('user/follow/<int:id>', views.user_follow, name='user-follow'),
    # user/follow/해당유저id 경로에서 user_follow를 보여준다.
]

마지막 콤마까지 주의.

user_view라는 함수에서 html 파일을 보여준다.

templates/user/user_list.html

# base.html을 확장하여 사용한다. 현재 base.html이 기본으로 붙어있는 상태. 상단 NaviBar
{% extends 'base.html' %}
{% block title %}
    사용자 리스트
{% endblock %}

{% block content %} # 실제 내용이 시작되는 구간.
    <div class="container timeline-container">
        <div class="row">
            <!-- 왼쪽 컬럼 (사용자이름 등 나오는 곳) -->
            <div class="col-md-3">
                <div class="card">
                    <div class="card-body">
                        <h5 class="card-title">{{ user.username }}</h5>
                        <p class="card-text"> {{ user.bio }}</p>

                    </div>
                </div>
            </div>
            <!-- 오른쪽 컬럼 (콘텐츠) -->
            <div class="col-md-7">
                <div class="row">
                    <div class="alert alert-success" role="alert">
                        나를 팔로우 하는 사람 수 : {{ user.followee.count }}/ 내가 팔로우 하는 사람 수 : {{ user.follow.count }}</div>
                </div>
                <div class="row">

그냥 user라고 하면 로그인된 사용자를 의미한다.

  • user.username 사용자이름.
  • user.bio 하고 싶은 말.

(user/models.py*를 참고한다.)

  • {{ user.followee(나를 팔로우하는 사람).count }} 나를 팔로우 하는 사람 수
  • {{ user.follow.count }} 내가 팔로우 하는 사람 수
    count를 떼면 내가 팔로우하는 모든 사람을 출력 가능.
# user_list
                    <!-- 사용자 리스트 반복문 -->
                    {% 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>

{% %} 안에서 python과 비슷하게 for, if문 등 사용 가능.

views.py에서 user_list로 전달했다. 리스트 형태의 사용자 전체 정보
for 반복문을 사용해서 하나씩 출력 : ul
해당 유저의 이름, 이메일, bio를 출력한다.

  • user/models.py*를 참고한다.
    • ul.followee 유저를 팔로우하는 사람들
    • ul.follow 유저가 팔로우하는 사람들
                                {% 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 %}
                </div>
            </div>
            <div class="col-md-2"></div>
        </div>
    </div>
{% endblock %}

/user/follow/{{ ul.id }}
(if) 팔로우한 사람들 중 하나의 유저ul가 있다면,

팔로우와 팔로우 취소는 같은 url을 실행한다.
views를 잘 작성했기 때문인데,
if문으로 follow 된 상태라면 팔로우 취소를 보여준다.
(else의 경우 팔로우)

위 페이지를 들어갈 url이 아직 없다.
user라는 url은 있지만 버튼으로 들어가는 게 좋겠다.
상단 내비게이션 바를 수정한다.

base.html

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

href="#"을 위와 같이 수정한다.


* user/models.py

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


# Create your models here.
class UserModel(AbstractUser):
    class Meta:
        db_table = "my_user"

    bio = models.CharField(max_length=256, default='')
    follow = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='followee')

follow 내가 팔로우할 사용자들 넣어 놓음.
그 사람들 입장에서는 내가 followee

  • UserModel.followee 유저를 팔로우하는 사람들
  • UserModel.follow 유저가 팔로우하는 사람들
profile
Español, Inglés, Coreano y Python

0개의 댓글