본문으로 바로가기

DRF | Community | 인기글 | 카테고리

category TIL 2022. 11. 12. 03:15

카테고리에 따른 게시판은 두개로 생각할 수 있었다.

1. MTM을 사용해서 카테고리 모델을 하나 더 만드는 방법

2. 게시글 모델에 카테고리를 넣어서 만드는 방법

처음에는 2 번을 생각해서 만들었다. 바로 만들 수 있을 것 같았다.

카테고리는 카테고리이름을 url로 들고와서 사용하고 인기글은 좋아요가 50개넘는 게시물만 들고오는 방법을 생각했다.

효율성으로는 1번이 조금 더 나은 것 같다

1번 사용시 게시글에 좋아요가 50개 넘으면 '인기글' 이라는 카테고리를 넣으면 될거라고 생각을 하고 url을 1개로 만들수 있을 것 같다.

2번은 url을 들고와서 사용하지만 사용자가 카테고리를 만들어서 작성하고 거기에 인기글 추가하면 되긴하네?... 흠....

주말에 시도해봐야 겠다.

 

오류

2번도중 인기글을 만들려고 하는데 인기글 쿼리셋에서 like가 안넘어온다 내가 짜보려고한 코드이다.

첫시도는 filter 사용을 id=post_id 이런식으로 사용만 했어서 부등호도 가능하다고 생각하면서 시작했다.

        posts=Post.objects.all()
        post=posts.filter(likes>2)

하지만 오류가 계속 떴고 불가능하다는 생각이 들었다. 이후에 리스트와 for문을 사용해서 시도했다.

class TopPostAPIView(APIView):
    def get(self, request):
        posts=Post.objects.all()
        print(posts.likes)
        b=[]
        for i in posts:
            if i.likes.count() > 0:
                b.append()
            else:
                print(b)
                pass
            print(b)
        serializer=PostSerializer(b, many=True)
        # print(serializer.data)
        return Response(serializer.data,status=status.HTTP_200_OK)

람다도 써보고 for문은 지금 사용해보는 중인데 MTM필드와 filter를 사용하는 방법을 공부해야 할 수 있을 것 같다.


해결

팀발표시간이 얼마남지않아서 마음이 바빴는지 거의 완성된 코드를 안된다고 생각해버렸다.

아래는 좋아요가 몇개이상인 글만 가져오는 코드이다.

우선 게시글 객체를 모두 들고온다.

그리고 변수에 리스트를 담아주고

for문으로 가져온 모든 객체를 돌면서 posts의 객체 하나하나씩 likes의 count를 보면서 어느숫자보다 크다면 리스트에 추가해준다

여기서 혹시모르는 오류를 피하기위해 else: pass 를 사용했는데 pass를 이렇게 사용을 해도 되는지는 의문이 든다.

from django.db.models import Count
class TopPostAPIView(APIView):
    def get(self, request):
        posts=Post.objects.all()

        top_posts = []
        for post in posts:
            if post.likes.count() > 1:
                top_posts.append(post)
                
        ----------------------- 아래는 원래코드
                
	 	posts=Post.objects.all()
        b=[]
        for i in posts:
            if i.likes.count() > 0:
                b.append()
            else:
                print(b)
                pass

        serializer=PostSerializer(top_posts, many=True)
        # print(serializer.data)
        return Response(serializer.data,status=status.HTTP_200_OK)

아래는 같은팀원이 알려준 코드이다. 함축식과 스택오버플로우를 참고해서 만들어본 코드이다.

class TopPostAPIView(APIView):
    def get(self, request):
    
        posts=Post.objects.all()
        top_posts = [post for post in posts if post.likes.count() > 1 ]

        serializer=PostSerializer(top_posts, many=True)
        # print(serializer.data)
        return Response(serializer.data,status=status.HTTP_200_OK)
from django.db.models import Count
class TopPostAPIView(APIView):
    def get(self, request):
    
        posts=Post.objects.all()
		top_posts = (Post.objects.annotate(num_likers = Count('likes'))).filter(num_likers__gte = 2)
        print(top_posts)

        # https://stackoverflow.com/questions/7883916/django-filter-the-model-on-manytomany-count
        # https://velog.io/@may_soouu/Django-%EB%A9%94%EC%86%8C%EB%93%9C-%EC%A0%95%EB%A6%AC

        serializer=PostSerializer(top_posts, many=True)
        # print(serializer.data)
        return Response(serializer.data,status=status.HTTP_200_OK)

결과

likes_count가 3개이상인 글만 get해오는걸 알 수 있다.