如何返回第一个序列化对象而不是Django中的所有对象?

时间:2019-04-30 13:37:45

标签: django django-rest-framework django-serializer

我有一个API(使用django-rest-framework),具有两个模型(例如Users和Cars)。

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

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

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

代码

汽车型号

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

我在寻找什么

给出两辆属于用户的汽车,其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
  }
}

我目前得到的东西

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
    }
  ],
}

谢谢,我很希望您能帮助我寻求解决方案。

3 个答案:

答案 0 :(得分: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')

这可以解决问题。


PS :如果您仍然希望将最新的汽车条目序列化为"car": { ... }而不是"last_car": { ... },则可以在{{1 }}本身:

CarSerializer

答案 1 :(得分: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)

答案 2 :(得分: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"
        }
    ]
}

波纹管给了我一个未知的错误,所以我用many = True编写了它

return CarSerializer(cars, many=False).data