如何删除重复的嵌套对象Django REST?

时间:2019-06-03 21:54:54

标签: django django-rest-framework

如何删除重复的嵌套注释Django REST? 序列化程序查询性显示注释。 在JSON重复注释中(第三个显示在两个位置): 如何摆脱它?

{
    "id": 1,
    "slug": "mp3kit",
    "publications_date": "2019-03-19T13:49:58Z",
    "tag": "Tag",
    "title": "Title",
    "content_preview": "Content preview",
    "body": "Body",
    "image_preview": null,
    "image_preview_name": "mp3kit",
    "comments": [
        {
            "name": "First",
            "body": "First",
            "date": "2019-06-02T15:09:16.788405Z",
            "id": "57fd0069-a8ce-484f-afac-4cc609a1b70c",
            "parent": null,
            "reply": [
                {
                    "name": "Third",
                    "body": "Third",
                    "date": "2019-06-02T15:09:42.512872Z",
                    "id": "0801ef96-796d-477b-8631-b21559527156",
                    "parent": "57fd0069-a8ce-484f-afac-4cc609a1b70c",
                    "reply": []
                }
            ]
        },
        {
            "name": "Second",
            "body": "Second",
            "date": "2019-06-02T15:09:27.209497Z",
            "id": "5b2f0d25-bcd0-4b19-b05c-e6a5e7de1280",
            "parent": null,
            "reply": []
        },
        {
            "name": "Third",
            "body": "Third",
            "date": "2019-06-02T15:09:42.512872Z",
            "id": "0801ef96-796d-477b-8631-b21559527156",
            "parent": "57fd0069-a8ce-484f-afac-4cc609a1b70c",
            "reply": []
        }
    ]
}

据我了解,您需要在ArticleSerializer的“ comment”字段上放置一个过滤器,以禁用带有父级的输出注释?

型号:

class Article(models.Model):
    id = models.AutoField(primary_key=True)
    slug = models.SlugField()
    publications_date = models.DateTimeField(blank=True, null=True, default=datetime.datetime.now)
    tag = models.CharField(max_length=100, blank=True, null=True)
    title = models.CharField(max_length=100, blank=True, null=True)
    content_preview = models.TextField(blank=True)
    body = HTMLField(blank=True, null=True)
    image_preview = models.ImageField(upload_to=upload_to, blank=True)
    image_preview_name = models.CharField(max_length=100, blank=True, null=True)

    def __str__(self):
        return self.title

    @property
    def comments_list(self):
        return self.comments.filter()


class Comment(models.Model):
    id = models.CharField(max_length=100, blank=True, unique=True, default=uuid.uuid4, primary_key=True)
    date = models.DateTimeField(auto_now=True, auto_now_add=False)
    name = models.CharField(max_length=100)
    body = models.TextField(blank=True, null=True)
    post = models.ForeignKey(Article, on_delete=models.CASCADE, blank=True,
                             related_name='comments', related_query_name='comment')
    parent = models.ForeignKey('self', related_name='reply', null=True, blank=True, on_delete=models.PROTECT)

    def __str__(self):
        return f'Post - "{self.post.title}", Body - "{self.body}"'

序列化器:

class RecursiveSerializer(serializers.Serializer):
    def to_representation(self, value):
        serializer = self.parent.parent.__class__(value, context=self.context)
        return serializer.data


class CommentSerializer(serializers.ModelSerializer):
    """DRF Serializer For Listing Published Comment"""
    reply = RecursiveSerializer(many=True, read_only=True)

    class Meta:
        model = Comment
        fields = [
            'name',
            'body',
            'date',
            'id',
            'parent',
            'reply'
        ]


class ArticleSerializer(serializers.ModelSerializer):
    comments = CommentSerializer(many=True)

    class Meta:
        model = Article
        lookup_field = 'slug'
        fields = (
            'id',
            'slug',
            'publications_date',
            'tag',
            'title',
            'content_preview',
            'body',
            'image_preview',
            'image_preview_name',
            'comments'
        )

观看次数:

class DetailArticle(generics.RetrieveUpdateDestroyAPIView):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    lookup_field = 'slug'

1 个答案:

答案 0 :(得分:0)

您可以通过在SerializerMethodField内使用ArticleSerializer来实现这一点,就像这样:

class ArticleSerializer(serializers.ModelSerializer):
    comments = serializers.SerializerMethodField()

    def get_comments(self, instance):
        return CommentSerializer(instance.comments.filter(parent__isnull=True), many=True).data

    class Meta:
        model = Article
        lookup_field = 'slug'
        fields = (
            'id',
            'slug',
            'publications_date',
            'tag',
            'title',
            'content_preview',
            'body',
            'image_preview',
            'image_preview_name',
            'comments'
        )