Drf: Getting related posts by ManyToMany category and a tags field

Viewed 63

I'm trying to get all related posts by getting the id of the current post and filtering through the DB to find posts that are either in a similar category or have similar tags.

this is the model for the posts:

class Post(models.Model):
    ....
    author = models.ForeignKey(
        "users.User", on_delete=models.CASCADE, related_name='blog_posts')
    tags = TaggableManager()
    categories = models.ManyToManyField(
        'Category')
    ....
    status = models.IntegerField(choices=blog_STATUS, default=0)

    def __str__(self):
        return self.title

this is the views.py file:

class RelatedPostsListAPIView(generics.ListAPIView):
    serializer_class = PostsSerializer
    queryset = BlogPost.objects.filter(
        status=1)[:5]
    model = BlogPost

def get_context_data(self, **kwargs):
    context = super(RelatedPostsListAPIView,
                    self).get_context_data(**kwargs)
    pk = self.kwargs['pk']
    main_post = BlogPost.objects.get(pk=pk)

    related_posts = main_post.filter(
        Q(categories__in=main_post.categories.all()) |
        Q(tags__in=main_post.tags.all())).exclude(pk=pk)[:5]

    context['related_posts'] = related_posts
    return context

this is the serializer

    class CategoriesSerializer(serializers.ModelSerializer):

    class Meta:
        model = Category
        fields = ['id', 'title', 'slug']


class PostsSerializer(TaggitSerializer, serializers.ModelSerializer):
    categories = CategoriesSerializer(many=True)
    author = UserSerializer()
    tags = TagListSerializerField()
    cover = serializers.SerializerMethodField('get_image_url')

    class Meta:
        model = BlogPost
        fields = [
            "id",
            "title",
            "slug",
            "author",
            "description",
            "content",
            "tags",
            "categories",
            "keywords",
            "cover",
            "created_on",
            "updated_on",
            "status",
        ]

    def get_image_url(self, obj):
        request = self.context.get("request")
        return request.build_absolute_uri(obj.cover.url)

url pattern:

urlpatterns = [
    path('all/', PostsListAPIView.as_view(), name="all_posts"),
    path('recent/', RecentPostsListAPIView.as_view(), name="recent_posts"),
    path('related/<int:pk>/', RelatedPostsListAPIView.as_view(), name="related_posts")
]

with this code I get a RelatedPostsListAPIView.get() got multiple values for argument 'pk' error, I don't think I am actually getting the object with the id, any help would be much appreciated.

1 Answers

You also have to capture request in get(), so change:

class RelatedPostsListAPIView(generics.ListAPIView):
    def get(self, pk):
        # ...

to:

class RelatedPostsListAPIView(generics.ListAPIView):
    def get(self, request, pk):
        #         ^^^ Add this
Related