не удается создать надлежащий древовидный структурированный вывод с использованием самоссылки с использованием django rest framework

#django #python-3.x #django-rest-framework #self-reference

#django #python-3.x #django-rest-framework #самоссылка

Вопрос:

У меня есть приведенная ниже модель комментариев, и я хочу реализовать функциональность комментариев-ответов и, в свою очередь, отправить ответ в виде JSON с использованием django rest framework. Но в ответе я получаю записи даже для ‘parent not equal to None’ в родительском узле. Я хочу, чтобы все записи, имеющие родительское значение, отображались только как дочерние.

models.py:

»’

 class Comment(models.Model):
    name = models.TextField('comment')
    expression = models.ForeignKey('Expression', on_delete=models.CASCADE, related_name='expression')
    datecreated = models.DateTimeField('date created', auto_now_add=True)
    dateupdated = models.DateTimeField('date updated', auto_now=True)
    parent = models.ForeignKey('self', on_delete=models.PROTECT, null=True, blank=True, related_name='replied_to')


    class META:
        verbose_name_plural = "comments"
        ordering = ['-datecreated']

    def __str__(self):
        return '{}'.format(self.name)
  

»’

views.py:

»’

 class CommentViewSet(viewsets.ModelViewSet):
    comments = Comment.objects.all()
    queryset = comments

    serializer_class = CommentSerializer

    @list_route()
    def roots(self, request, *args, **kwargs):
        slug = kwargs.get('slug')

        expression = Expression.objects.get(author=request.user, slug=slug)
        queryset = expression.expression.filter(parent=None)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
  

»’

serializers.py:

»’

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

class CommentSerializer(serializers.ModelSerializer):
    '''
    Ref: http://voorloopnul.com/blog/representing-hierarchical-data-with-django-rest-framework/
    '''
    expression = serializers.CharField(required=False, read_only=True)
    replied_to = RecursiveSerializer(many=True, read_only=True)

    class Meta:
        model = Comment
        read_only_fields = ('id','datecreated', 'dateupdated',)
        fields = ('id','name','expression','datecreated','dateupdated','parent','replied_to')
  

»’

Фактический результат:

»’

 [
    {
        "id": 5,
        "name": "my new comment",
        "expression": "My new expression",
        "datecreated": "2019-04-19T15:38:23.174877 05:30",
        "dateupdated": "2019-04-19T15:38:23.174877 05:30",
        "parent": null,
        "replied_to": [
            {
                "id": 6,
                "name": "my sub comment",
                "expression": "My new expression",
                "datecreated": "2019-04-19T15:38:55.061534 05:30",
                "dateupdated": "2019-04-23T23:56:01.846904 05:30",
                "parent": 5,
                "replied_to": [
                    {
                        "id": 7,
                        "name": "my sub sub comment",
                        "expression": "My new expression",
                        "datecreated": "2019-04-19T15:42:46.981884 05:30",
                        "dateupdated": "2019-04-23T23:56:38.131256 05:30",
                        "parent": 6,
                        "replied_to": []
                    }
                ]
            }
        ]
    },
    {
        "id": 6,
        "name": "my sub comment",
        "expression": "My new expression",
        "datecreated": "2019-04-19T15:38:55.061534 05:30",
        "dateupdated": "2019-04-23T23:56:01.846904 05:30",
        "parent": 5,
        "replied_to": [
            {
                "id": 7,
                "name": "my sub sub comment",
                "expression": "My new expression",
                "datecreated": "2019-04-19T15:42:46.981884 05:30",
                "dateupdated": "2019-04-23T23:56:38.131256 05:30",
                "parent": 6,
                "replied_to": []
            }
        ]
    },
    {
        "id": 7,
        "name": "my sub sub comment",
        "expression": "My new expression",
        "datecreated": "2019-04-19T15:42:46.981884 05:30",
        "dateupdated": "2019-04-23T23:56:38.131256 05:30",
        "parent": 6,
        "replied_to": []
    }
]
  

»’

Ожидаемый вывод:

»’

 [
    {
        "id": 1,
        "name": "new comment1",
        "expression": "My new expression1",
        "datecreated": "2019-04-07T17:52:52.784429 05:30",
        "dateupdated": "2019-04-07T17:52:52.784429 05:30",
        "parent": null,
        "replied_to": []
    },
    {
        "id": 5,
        "name": "my new comment",
        "expression": "My new expression",
        "datecreated": "2019-04-19T15:38:23.174877 05:30",
        "dateupdated": "2019-04-19T15:38:23.174877 05:30",
        "parent": null,
        "replied_to": [
            {
                "id": 6,
                "name": "my sub comment",
                "expression": "My new expression",
                "datecreated": "2019-04-19T15:38:55.061534 05:30",
                "dateupdated": "2019-04-23T23:56:01.846904 05:30",
                "parent": 5,
                "replied_to": [
                    {
                        "id": 7,
                        "name": "my sub sub comment",
                        "expression": "My new expression",
                        "datecreated": "2019-04-19T15:42:46.981884 05:30",
                        "dateupdated": "2019-04-23T23:56:38.131256 05:30",
                        "parent": 6,
                        "replied_to": []
                    }
                ]
            }
        ]
    },
]
  

»’

Ответ №1:

Изменил представления, как показано ниже: «‘

 class CommentViewSet(viewsets.ModelViewSet):
    queryset = Comment.objects.all()

    serializer_class = CommentSerializer

    def list(self, request, **kwargs):
        slug = kwargs.get('slug')
        try:
            expression = Expression.objects.get(author=request.user, slug=slug)
            queryset = expression.expression.filter(parent=None)
            serializer = self.get_serializer(queryset, many=True)
            return Response(serializer.data)
        except Expression.DoesNotExist as err:
            return Response(data={'error':'Expression matching query does not exist.'}, status=status.HTTP_404_NOT_FOUND)
  

»’

Теперь я получаю желаемую иерархию, как показано ниже:

»’

 [
    {
        "id": 5,
        "name": "my new comment",
        "expression": "My new expression",
        "datecreated": "2019-04-19T15:38:23.174877 05:30",
        "dateupdated": "2019-04-19T15:38:23.174877 05:30",
        "parent": null,
        "replied_to": [
            {
                "id": 6,
                "name": "my sub comment",
                "expression": "My new expression",
                "datecreated": "2019-04-19T15:38:55.061534 05:30",
                "dateupdated": "2019-04-23T23:56:01.846904 05:30",
                "parent": 5,
                "replied_to": [
                    {
                        "id": 7,
                        "name": "my sub sub comment",
                        "expression": "My new expression",
                        "datecreated": "2019-04-19T15:42:46.981884 05:30",
                        "dateupdated": "2019-04-23T23:56:38.131256 05:30",
                        "parent": 6,
                        "replied_to": []
                    }
                ]
            }
        ]
    },
    {
        "id": 8,
        "name": "new test user comment",
        "expression": "My new expression",
        "datecreated": "2019-04-24T00:43:57.939082 05:30",
        "dateupdated": "2019-04-24T00:43:57.939082 05:30",
        "parent": null,
        "replied_to": []
    }
]
  

»’