Django REST Framework: показывать только последний вложенный объект, возвращать как не вложенный JSON - PullRequest
1 голос
/ 29 октября 2019

Что я пытаюсь сделать в Django REST Framework: вернуть только последний вложенный объект в списке для объекта и вернуть его как JSON, с вложенным вложенным объектом.

Мои модели:

class BaseObject(models.Model):
   name = models.TextField()
   object_type = models.ForeignKey(ObjectType)


class ObjectStatus(models.Model):
   baseobject_id = models.ForeignKey('objects.BaseObject', related_name='status')
   object_status = models.IntegerField()
   object_status_timestamp = models.DateTimeField()

Мои сериализаторы:

class ObjectStatusSimplifiedSerializer(serializers.ModelSerializer):  #helper serializer to simplify status objects
   class Meta:
       model = ObjectStatus
       fields = ['object_status', 'object_status_timestamp']


class ObjectStatusListSerializer(serializers.ModelSerializer):  #request for last status of several objects
   status = ObjectStatusSimplifiedSerializer(many=True)

   class Meta:
       model = BaseObject
       fields = ['id', 'name', 'object_type', 'status']

Мой текущий просмотр:

class ObjectStatusListView(generics.ListCreateAPIView):
   serializer_class = ObjectStatusListSerializer

   def get_queryset(self):
       queryset = BaseObject.objects.all()
       id = self.request.query_params.getlist('id')
       if id:
           queryset = queryset.filter(id__in=id)
           return queryset

Текущий URL:

url(r'^objectstatus/status/list$', views.ObjectStatusListView.as_view()),

Так что теперь, когда собираюсьнапример, [...]/objectstatus/status/list?id=9, результат, который я получаю, выглядит следующим образом:

[
    {
        "id": 9,
        "name": "r5",
        "object_type": "router",
        "status": [
            {
                "object_status": 1,
                "object_status_timestamp": "2019-10-24T09:40:15.605391Z"
            },
            {
                "object_status": 2,
                "object_status_timestamp": "2019-10-24T09:40:28.133296Z"
            },
            {
                "object_status": 3,
                "object_status_timestamp": "2019-10-24T09:40:40.829486Z"
            },
            {
                "object_status": 1,
                "object_status_timestamp": "2019-10-24T09:40:53.333332Z"
            }
        ]
    }
]

Мне нужно, чтобы отображалось только состояние объекта с самой последней отметкой времени.

Кроме того,Я не могу понять, как сгладить объект JSON, например:

[
    {
        "id": 9,
        "name": "r5",
        "object_type": "router",
        "object_status": 1,
        "object_status_timestamp": "2019-10-24T09:40:53.333332Z"
    }
]

Ответы [ 2 ]

1 голос
/ 29 октября 2019

С помощью следующего сериализатора вы должны получить желаемый результат. Мы фильтруем список статусов и получаем только последний, а затем выравниваем структуру по мере необходимости.

class ObjectStatusListSerializer(serializers.ModelSerializer):  #request for last status of several objects
   status = serializers.SerializerMethodField(read_only=True)

   class Meta:
       model = BaseObject
       fields = ['id', 'name', 'object_type', 'status']


    def get_status(self, obj):
       return ObjectStatusSimplifiedSerializer(instance=obj.status.order_by('object_status_timestamp').first()).data

    def to_representation(self, obj):
        """Move fields from status to main object representation."""
        representation = super().to_representation(obj)
        status_representation = representation.pop('status')
        for key in status_representation:
            representation[key] = status_representation[key]

        return representation
1 голос
/ 29 октября 2019

вы можете попробовать изменить serializer на подобное. Я предполагаю, что у вашего ObjectType есть поле name для кода линии object_type.name

class ObjectStatusSimplifiedSerializer(serializers.ModelSerializer):
    name = serializers.SerializerMethodField()
    object_type = serializers.SerializerMethodField()

    @staticmethod
    def get_name(instance):
        return instance.status.name

    @staticmethod
    def get_object_type(instance):
        return instance.status.object_type.name

    class Meta:
        model = ObjectStatus
        fields = ['id', 'name', 'object_type', 'object_status', 'object_status_timestamp']

class ObjectStatusListSerializer(serializers.ModelSerializer):
    status = serializers.SerializerMethodField()

    @staticmethod
    def get_status(instance):
        queryset = ObjectStatus.objects.filter(baseobject_id=instance).order_by('-object_status_timestamp')[:1]
        if queryset.count():
            return ObjectStatusSimplifiedSerializer(queryset, many=True).data
        return []

    class Meta:
        model = BaseObject
        fields = ['id', 'name', 'object_type', 'status']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...