如何在Django中返回第一个序列化对象而不是全部?

问题描述 投票:0回答:3

我有一个API(使用django-rest-framework)和两个模型(例如用户和汽车)。

我试图让用户的最新(最高ID)汽车在查询用户时也返回。

我尝试在用户序列化器中包含cars = CarSerializer(many=True),它返回该用户的所有汽车。

我试过cars = CarSerializer(many=False),它返回我想要的格式,但没有车出现。

Code

汽车模型

class Car(models.Model):
    name = models.TextField(default='')
    year = models.IntegerField(null=True)
    owner = models.ForeignKey('User', related_name='cars')

汽车系列化器

class CarSerializer(serializers.ModelSerializer):

    class Meta:
        model = Car
        fields = ('id', 'name', 'year', 'owner')

用户序列化器

class UserSerializer(serializers.ModelSerializer):
    car = CarSerializer(many=True)

    class Meta:
        model = User
        fields = ('id', 'first_name', 'last_name', 'car')

汽车视图

class CarViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Car.objects.all()
    serializer_class = CarSerializer

用户视图

class UserViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

What I'm looking for

给定属于ID为1的用户的两辆车:

id: 1
owner: 1
name: "kinda okay car"
year: 2012

id: 2
owner: 1
name: "the fastest one"
year: 2020

GET / users / 1的JSON结果

{
  "id": 1,
  "first_name": "Bob",
  "last_name": "McFastCar",
  "car": {
    "name": "the fastest one",
    "year": 2020
  }
}

What I currently get

GET / users / 1的JSON结果

{
  "id": 1,
  "first_name": "Bob",
  "last_name": "McFastCar",
  "cars": [
    {
      "id": 2,
      "owner": 1
      "name": "the fastest one",
      "year": 2020
    },
    {
      "id": 1,
      "owner": 1
      "name": "kinda okay car",
      "year": 2012
    }
  ],
}

谢谢,我希望你能帮助我找到解决方案。

django django-rest-framework django-serializer
3个回答
1
投票

你可以在你的@property模型中创建一个仅返回最后一辆车的User

class User:
    ...

    @property
    def last_car(self):
        return self.cars.last()

然后在UserSerializer中你可以序列化这个属性:

class UserSerializer:
    last_car = CarSerializer(read_only=True)

    class Meta:
        model = User
        fields = (..., 'last_car')

这样就可以了。


附: :如果你仍然希望你的最新车型被序列化为"car": { ... }而不是"last_car": { ... },你可以在the source attribute上使用CarSerializer

class UserSerializer:
    car = CarSerializer(source='last_car', read_only=True)
    ...

0
投票

CarSerializer必须与查询集或对象链接,否则它将返回所有对象

# get the car object with the highest using order_by
car =  Car.objects.all().order_by('-id')[0]
# build a car serializer from the car object
car_serializer = CarSerializer(car, many=False)

0
投票

您可以像下面这样编写UserSerializers

class UserSerializer(serializers.ModelSerializer):
    cars = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = ('id', 'first_name', 'last_name', 'cars')

    def get_cars(self, instance):
        cars = instance.cars.all().order_by('-year')
        return CarSerializer([cars[0], ], many=True).data

并调用GET /users/1将返回这样的结果

{
    "id": 2,
    "first_name": "Bob",
    "last_name": "McFastCar",
    "cars": [
        {
            "id": 2,
            "name": "the fastest one",
            "year": 2020,
            "owner": 2,
            "first_name": "Bob"
        }
    ]
}

波纹管线给了我一个未知的错误,所以我写了很多=真

return CarSerializer(cars, many=False).data
© www.soinside.com 2019 - 2024. All rights reserved.