Article과 User의 M:N 관계 설정을 통해 좋아요 기능을 구현해보자.
# articles/models.py
from django.db import models
from django.conf import settings
# Create your models here.
class Article(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
like_users = models.ManyToManyField(settings.AUTH_USER_MODEL)
title = models.CharField(max_length=30)
content = models.TextField()
image = models.ImageField(blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return f'{self.id}번째글 - {self.title}'
$ python manage.py makemigrations
SystemCheckError: System check identified some issues:
ERRORS:
articles.Article.like_user: (fields.E304) Reverse accessor for 'articles.Article.like_user' clashes with reverse accessor for 'articles.Article.user'.
HINT: Add or change a related_name argument to the definition for 'articles.Article.like_user' or 'articles.Article.user'.
articles.Article.user: (fields.E304) Reverse accessor for 'articles.Article.user' clashes with reverse accessor for 'articles.Article.like_user'.
HINT: Add or change a related_name argument to the definition for 'articles.Article.user' or 'articles.Article.like_user'.
like_users 필드 생성 시 자동으로 역참조에는 .article_set 매니저가 생성됨
그러나 이전 N:1(Article-User) 관계에서 이미 해당 매니저를 사용 중
user와 관계된 ForeignKey 혹은 ManyToManyField 중 하나에 related_name을 작성해야 함
ManyToManyField에 related_name 작성 후 Migration
from django.db import models
from django.conf import settings
# Create your models here.
class Article(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
like_users = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='like_articles')
title = models.CharField(max_length=30)
content = models.TextField()
image = models.ImageField(blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return f'{self.id}번째글 - {self.title}'
article.user
: 게시글을 작성한 유저 - N:1user.article_set
: 유저가 작성한 게시글(역참조) - N:1article.like_users
: 게시글을 좋아요한 유저 - M:Nuser.like_articles
: 유저가 좋아요한 게시글(역참조) - M:N# articles/urls.py
from django.urls import path
from . import views
app_name = 'articles'
urlpatterns = [
...,
path('<int:article_pk>/likes/', views.likes, name='likes'),
]
# articles/views.py
def likes(request, article_pk):
article = Article.objects.get(pk=article_pk)
if article.like_users.filter(pk=request.user.pk).exists():
article.like_users.remove(request.user)
else:
article.like_users.add(request.user)
return redirect('articles:index')
.exists()
<!-- articles/index.html -->
{% for article in articles %}
<p>
[{{article.id}}]
<a href="{% url 'articles:detail' article.pk %}" id="article-title">{{article.title}}</a>
- 작성자: {{article.user}}
</p>
<hr />
<div>
<form action="{% url 'articles:likes' article.pk %}" method="POST">
{% csrf_token %}
{% if request.user in article.like_users.all %}
<input type="submit" value="좋아요 취소">
{% else %}
<input type="submit" value="좋아요">
{% endif %}
</form>
</div>
{% endfor %}
좋아요 버튼 출력 확인
버튼 클릭 후 좋아요 테이블 확인
# articles/views.py
def likes(request, article_pk):
if request.user.is_authenticated:
article = Article.objects.get(pk=article_pk)
if article.like_users.filter(pk=request.user.pk).exists():
article.like_users.remove(request.user)
else:
article.like_users.add(request.user)
return redirect('articles:index')
return redirect('accounts:login')
<p>{{ article.like_users.all.count }} 명이 이 글을 좋아합니다.</p>
https://github.com/mjieun0956/TIL/tree/master/Database/06.%20Article-User%20(LIKE)