Djangoroidの奮闘記

python,django,angularJS1~三十路過ぎたプログラマーの奮闘記

Django REST Frameworkに再挑戦 その17 Comment URLs & Post Get API Urls

概要

Django REST Frameworkに再挑戦 その17 Comment URLs & Post Get API Urls

参考サイト

www.django-rest-framework.org

www.codingforentrepreneurs.com

Comment URLs & Post Get API Urls

  • CommentListAPIViewのコードを修正する。
class CommentListAPIView(ListAPIView):
    # queryset = Post.objects.all()
    serializer_class = CommentListSerializer # ここを修正
    filter_backends = [SearchFilter, OrderingFilter]
    search_fields = ['content', 'user__first_name']
    pagination_class = PostPageNumberPagination#PageNumberPagination

    def get_queryset(self, *args, **kwargs):
        #queryset_list = super(PostListAPIView, self).get_queryset(*args, **kwargs)
        queryset_list = Comment.objects.filter(id__gte=0)
        # フィルターを使いたい場合は、queryset_list = Post.objects.filter(user=self.request.user)
        query = self.request.GET.get("q")
        if query:
            queryset_list = queryset_list.filter(
                    Q(content__icontains=query)|
                    Q(user__first_name__icontains=query) |
                    Q(user__last_name__icontains=query)
                    ).distinct()
        return queryset_list
  • DetailViewのURLをゲットする。
...
class CommentListSerializer(ModelSerializer):
    url = HyperlinkedIdentityField(
        view_name='comments-api:thread',)
    reply_count = SerializerMethodField()
    class Meta:
        model = Comment
        fields = [
            'url',
...
  • CommentDetailSerializerにも、urlを定義する。ここでは、postのurlを定義する。(コメント自身のURLではなく)
class CommentDetailSerializer(ModelSerializer):
    reply_count = SerializerMethodField()
    content_object_url = SerializerMethodField()
    replies = SerializerMethodField()
    class Meta:
        model = Comment
        fields = [
            'id',
            # 'content_type',
            # 'object_id',
            'content',
            'reply_count',
            'replies',
            'timestamp',
            'content_object_url',
        ]
        read_only_fields = [
            # 'content_type',
            # 'object_id',
            'reply_count',
            'replies',
        ]

    def get_content_object_url(self, obj):
        return obj.content_object.get_absolute_url()
        # obj.content_objectだと、postのget_absolute_url
        # obj だとcommentのget_absolute_url
  • get_content_object_urlをさらに少し修正する。get_absoluteではなく、apiのviewを表示させるようにする。(なぜなら、get_absoluteでは、APIではなく、djangoのCBVを利用したviewの方を表示してしまうため)
    def get_content_object_url(self, obj):
        try:
            return obj.content_object.get_api_url()
        except:
            return None
  • post/models.pyにget_api_urlを作成する。
class Post(models.Model):
...
    def get_api_url(self):
        return reverse("posts-api:detail", kwargs={"slug": self.slug})
...
  • これで、apiのurlはゲットできる〜!djangoも便利!