[DRF] annotate

JinUk Lee·2023년 7월 10일
0

DRF 학습하기

목록 보기
32/54

게시판의 추천 글 모아보는 기능을 구현해보고 싶었다.

# models.py

subject_list = [
        ('일반','일반'),
        ('정보','정보'),
        ('사진','사진'),
        ('공략','공략'),
        ('자랑','자랑'),
]

class Article(models.Model):

    title = models.CharField(max_length=80)
    content = models.TextField()
    createuser = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    hits_field = models.IntegerField(default=0)
    created_at = models.DateTimeField(auto_now_add=True, null=False, blank=False)
    updated_at = models.DateTimeField(auto_now=True, null=False, blank=False)
    subject = models.CharField(max_length=50, choices=subject_list)
    

    def __str__(self):
        return self.title

class LikeArticle(models.Model):

    article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='article_name')
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="article_like_user"
    )

모델은 이렇게 구성되어있다.

추천수를 api에서 제공하기 위해 serializers.py 에서 아래와 같이 구현했다.



class ArticleSerializer(serializers.ModelSerializer):
    images = serializers.SerializerMethodField()
    createusernickname = serializers.ReadOnlyField(source='createuser.nickname')
    hits = serializers.ReadOnlyField(source = 'hits_field')
    comments = CommentNestedSerializer(many=True, read_only=True)
    like_article = LikeArticleSerializer(many=True, read_only=True)
    like_count = serializers.IntegerField(source="article_name.count", read_only=True)

그러나 serializer에서 만든 추천수로는 filter을 사용할 수 없었다.

그래서 view에서 annotate를 활용하여 추천수로 필터링했다.



class BestArticleView(viewsets.ModelViewSet):

    serializer_class = ArticleSerializer

    queryset = Article.objects.annotate(count=Count('article_name')).filter(count__gt=30).order_by('-count')

annotate란 가상의 속성을 만들어주는 것이다.
위의 코드에서 count라는 가상의 속성을 만들고 이것을 Count('article_name') 라고 article_name 속성의 수라는 값을 주었다.

이 값을 filter에서 사용하여 추천수 30으로 필터링 하는 방식이다.

profile
개발자 지망생

0개의 댓글