ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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
Designed by Tistory.