DRF:通过 ManyToMany 类别和标签字段获取相关帖子
Drf: Getting related posts by ManyToMany category and a tags field
我正在尝试通过获取当前 post 的 ID 并通过数据库过滤以查找类似的 posts 来获取所有相关的 posts类别或具有相似标签。
这是 post 的模型:
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
这是 views.py 文件:
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
这是序列化程序
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 模式:
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")
]
使用这段代码我得到一个 RelatedPostsListAPIView.get() got multiple values for argument 'pk'
错误,我不认为我实际上得到了带有 id 的对象,任何帮助将不胜感激。
您还必须在 get()
中捕获 request
,因此更改:
class RelatedPostsListAPIView(generics.ListAPIView):
def get(self, pk):
# ...
至:
class RelatedPostsListAPIView(generics.ListAPIView):
def get(self, request, pk):
# ^^^ Add this
我正在尝试通过获取当前 post 的 ID 并通过数据库过滤以查找类似的 posts 来获取所有相关的 posts类别或具有相似标签。
这是 post 的模型:
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
这是 views.py 文件:
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
这是序列化程序
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 模式:
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")
]
使用这段代码我得到一个 RelatedPostsListAPIView.get() got multiple values for argument 'pk'
错误,我不认为我实际上得到了带有 id 的对象,任何帮助将不胜感激。
您还必须在 get()
中捕获 request
,因此更改:
class RelatedPostsListAPIView(generics.ListAPIView):
def get(self, pk):
# ...
至:
class RelatedPostsListAPIView(generics.ListAPIView):
def get(self, request, pk):
# ^^^ Add this