-
Django Model Relationship (M:N)Django 2024. 8. 27. 01:25
좋아요와 팔로우 기능은 어떻게 만드는 걸까🤔
하나의 게시글도 여러명의 유저에게 좋아요를 받을 수 있고, 한 명의 유저는 여러개의 게시글을 좋아할 수 있다.
즉, 다대다(M:N) 관계 설정시 사용하는 모델 필드를 사용하면 된다.
- Django에서도 models.ManyToManyField(<classname>)을 이용해서 설정이 가능하다.
- M:N 관계가 설정되면 역참조시 사용가능한 _set이름의 RelatedManager를 생성한다. (related_name 으로 변경 가능)
- add(), remove()를 이용해서 관련 객체를 추가, 삭제할 수 있다.
좋아요 구현하기
articles/models.py 수정
class Article(models.Model): ... like_users = models.ManyToManyField( settings.AUTH_USER_MODEL, related_name="like_articles" )
사실 articles 에 만들어도 되고 users 에 만들어줘도 된다. users 앱에 만들거면 like_articles 로 해주면 된다😊
📌 장고는 m2m 필드를 추가하면 자동으로 중계테이블을 설정한다.
그 다음 > migration 실행
잘 만들어졌다.
articles/urls
urlpatterns = [ ... path("<int:pk>/like/", views.like, name="like"), ... ]
articles/views
@require_POST def like(request, pk): if request.user.is_authenticated: article = get_object_or_404(Article, pk=pk) if article.like_users.filter(pk=request.user.pk).exists(): article.like_users.remove(request.user) else: article.like_users.add(request.user) else: return redirect("accounts:login") return redirect("articles:articles")
articles.html
{% for article in articles %} ... <form actions="{% url "article:like" article.pk %}" method="POST"> {% csrf_token &} {% if user in article.like_users.all %} <input type="sumit" value="안좋아요"> {% else %} <input type="sumit" value="좋아요"> {% endif %} </form> {% endfor %}
팔로우 구현하기
팔로우 가능도 마찬가지다.
한 명의 유저가 여러명의 유저를 팔로우 할 수 있고, 한 명의 유저는 여러명의 팔로워를 가질 수 있다. → 즉, M:N관계
accounts/models.py
from django.db import models from django.contrib.auth.models import AbstractUser class User(AbstractUser): following = models.ManyToManyField( "self", symmetrical=False, related_name="followers" )
그런 다음에는 마이그래이션 해줘야 한다.
python manage.py makemigrations
python manage.py migrate
마이그래이션 후에 생성된 테이블을 확인해보면, 생성된 테이블을 확인할 수 있다.
users/urls.py
from django.urls import path from . import views app_name = "users" urlpatterns = [ ... path("<int:user_id>/follow/", views.follow, name="follow"), ]
users/views.py
from django.shortcuts import render, redirect from django.views.decorators.http import require_POST from django.shortcuts import get_object_or_404 from django.contrib.auth import get_user_model def users(request): return render(request, "users/users.html") def profile(request, username): member = get_object_or_404(get_user_model(), username=username) context = { "member": member, } return render(request, "users/profile.html", context) @require_POST def follow(request, user_pk): if request.user.is_authenticated: member = get_object_or_404(get_user_model(), pk=user_pk) if request.user != member: if request.user in member.followers.all(): member.followers.remove(request.user) else: member.followers.add(request.user) return redirect("users:profile", member.username) return redirect("accounts:login")
profile.html
{% extends 'base.html' %} {% block content %} <h1>{{ member.username }}의 프로필 페이지</h1> <div> <h2>username : {{ member.username }}</h2> <p> 팔로워 : {{ member.followers.count }}명 팔로잉 : {{ member.following.count }}명 </p> </div> <div> <form action="{% url "users:follow" member.pk %}" method="POST"> {% csrf_token %} {% if user in member.followers.all %} <button type="submit">언팔로우</button> {% else %} <button type="submit">팔로우</button> {% endif %} </form> </div> <a href="/index/">홈으로 돌아가기</a> {% endblock content %}
직접 해봐야 제대로 알 수 있다!
튜터님은 쉽게 되는데.. .난 똑같이 하는데도 쉽지가 않다.😥
'Django' 카테고리의 다른 글
JSON Response와 Serialization (1) 2024.09.01 HTTP와 URL구조 (1) 2024.08.29 Django Custom UserModel (0) 2024.08.19 Djnago Model Relationship (1:N) (0) 2024.08.19 Django 관리자 페이지 (Admin Site) (0) 2024.08.19