我尝试使用ContentTypes Framework和DRF。我已阅读generic relationships
文档我已经形成了BlogPost
模型:
class BlogPost(models.Model):
user = models.ForeignKey(User, default=1, null=True, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
comments = GenericRelation(Comment)
和Comment
型号:
class Comment(models.Model):
comment_author = models.ForeignKey(User, default=1, null=True, on_delete=models.CASCADE)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
我组成了serializers
:
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = "__all__"
class CommentedObjectRelatedField(serializers.RelatedField):
def to_representation(self, value):
"""
Serialize tagged objects to a simple textual representation.
"""
if isinstance(value, Comment):
serializer = CommentSerializer(value)
else:
raise Exception('Unexpected type of commented object')
return serializer.data
class BlogPostSerializer(serializers.HyperlinkedModelSerializer):
comments = CommentedObjectRelatedField(many=True, read_only=True)
time_since_publication = serializers.SerializerMethodField()
def get_time_since_publication(self, object):
publication_date = object.published_at
now = datetime.now()
time_delta = timesince(publication_date, now)
return time_delta
class Meta:
model = BlogPost
fields = ['id', 'pk', 'title', 'slug', 'content','comments', 'published_at', 'timestamp', 'updated', 'time_since_publication']
read_only_fields = ('pk',)
lookup_field = ('pk',)
当我在浏览器中检查api
时,我会得到json
答案
[
{
"id": 1,
"pk": 1,
"title": "this is title",
"slug": "this-is-title",
"content": "This is content",
"comments": null,
"published_at": "2019-11-15",
"timestamp": "2019-11-15T12:14:37.336170Z",
"updated": "2019-11-15T12:14:37.336208Z",
"time_since_publication": "16 hours, 5 minutes"
}
]
如何获得相关评论。 谢谢
ps:这是我的视图函数
class BlogPostListCreateAPIView(generics.ListCreateAPIView):
queryset = BlogPost.objects.all()
serializer_class = BlogPostSerializer
def post(self, request, *args, **kwargs):
title = request.data['title']
self.slug = slugify(title)
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def perform_create(self, serializer):
serializer.save()
class CommentListCreateAPIView(generics.ListCreateAPIView):
queryset = BlogPost.objects.all()
serializer_class = BlogPostSerializer
def perform_create(self, serializer):
blogpost_pk = self.kwargs.get("pk")
blogpost = get_object_or_404(BlogPost, pk=pk)
serializer.save()
class CommentDetailAPIView(generics.RetrieveUpdateDestroyAPIView):
queryset = BlogPost.objects.all()
serializer_class = BlogPostSerializer
答案 0 :(得分:0)
好像您已切换通用关系和反向通用关系。在您引用的示例中,要序列化的对象是TaggedItem
,这是具有通用外键的模型。但是在您的代码中,您尝试序列化一个BlogPost
对象(即关系的另一面)的GenericRelation
对象。从文档中:
请注意,使用GenericRelation表示的反向通用密钥 字段,可以使用常规关系字段类型进行序列化, 因为关系中目标的类型总是已知的。
尝试简单地从序列化程序中删除CommentedObjectRelatedField
行。让HyperlinkedModelSerializer
处理关系。
在一个粗略的本地尝试中,将字段留在外面是行不通的(在这种情况下,我得到一个异常,指出“ GenericRelatedObjectManager类型的对象不可JSON序列化”)。我必须在序列化器中明确添加一个HyperlinkedRelatedField
。