[Django] 비 SPA 방식으로 장고 Forms/Views를 적극 활용한 인스타그램 St 만들기#11_포스팅 좋아요/취소 구현

아직·2022년 7월 15일
0
post-thumbnail

1)

class Post(BaseModel):
    like_user_set = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True)

class LikeUser(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    user = models.ForeignKey(settings.AUTH_USER_MODEL. on_delete=models.CASCADE)

M:N 관계를 설정할 때 중요한 건 부모 테이블의 설정인 것 같다. 아래는 post의 부모 Post와, user의 부모 AUTH_USER_MODEL이 보다 명시적으로 적혀있다. 위는 더 일반적인 ManyToManyField의 선언인데 여기서도 Post와 AUTH_USER_MODEL을 확인할 수 있다. 이때 둘을 묶어주는 like_user_set이 User의 instance들의 묶음처럼 이해될 수 있음에 주목하자.

2)

class Post(BaseModel):

	author = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='my_post_set',
                               on_delete=models.CASCADE)
    
    like_user_set = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True)
+
ERRORS:
instagram.Post.author: (fields.E304) Reverse accessor for 'instagram.Post.author' clashes with reverse accessor for 'instagram.Post.like_user_set'.
        HINT: Add or change a related_name argument to the definition for 'instagram.Post.author' or 'instagram.Post.like_user_set'.
instagram.Post.like_user_set: (fields.E304) Reverse accessor for 'instagram.Post.like_user_set' clashes with reverse accessor for 'instagram.Post.author'.        
        HINT: Add or change a related_name argument to the definition for 'instagram.Post.like_user_set' or 'instagram.Post.author'.

Post.objects.filter(author=user)와 user.post_set.all()은 같은 결과 값을 반환하는데 like_user_set 코드를 활성화했을 때 post_set과 충돌이 났다.

각각의 relasted_name을 'my_post_set', 'like_post_set'으로 변경한다.

Post 클래스-User 외래키의 경우 user.my_post_set만 가능하고 Post 클래스-User M:N의 경우 (like_user_set을 동시에 설정해 줌으로써) user.like_post_set뿐만 아니라, post.like_user_set까지 양 객체를 중심으로 모음을 만들 수 있다.

3)

from django import template

register = template.Library()


@register.filter
def is_like_user(post, user)
 return post.ik_like_user(user)
+
{% load instagram_tags %}
...
{ post|is_like_user:user}

{{ post.is_like_user(user) }}

템플릿에서는 인스턴스의 함수까지는 호출할 수 있지만, 인자를 넘길 수는 없어서 templatetags를 이용했다. 독립 py 파일에 구현한 부분을 필터처럼 사용한다.

4)

{% if post|is_like_user:user %}
            <a href="{% url "instagram:post_unlike" post.pk %}" style="color: inherit;">
                <i class="fa fa-heart"></i>
            </a>
{% else %}
            <a href="{% url "instagram:post_like" post.pk %}">
                <i class="fa fa-heart"></i>
            </a>
{% endif %}

좋아요를 누르거나 취소했을 때 페이지를 이동하는 것은 js에 의해서 ajax 요청을 보내는 것이 아니라 브라우저에서 지원하는 기능을 이용해서 그렇다.

0개의 댓글