Django DRF多模型视图

时间:2015-12-15 16:18:00

标签: python django django-rest-framework

我想在一个请求中检索几个模型,所以我会得到:

{
  "cars": [
    {
      "id": "1",
      "name": "foo"
    }
  ],
  "trucks": [
    {
      "id": "1",
      "name": "goo"
    }
  ],
  "bikes": [
    {
      "id": "1",
      "name": "doo"
    }
  ],
}

为此我创建了一个序列化器:

class VehiclesSerializer(serializers.Serializer):

    cars = CarSerializer(many=True, read_only=True)
    trucks = TruckSerializer(many=True, read_only=True)
    bikes = BikeSerializer(many=True, read_only=True)

和观点:

class VehiclesListView(generics.ListAPIView):

    queryset = ???????
    serializer_class = VehiclesSerializer

但正如您所看到的,我还没有设法弄清楚如何编写查询集。

有任何帮助吗?

UPDATE:

只是为了澄清我的问题。没有车型。 这就是为什么我写常规的原因 queryset = Vehicles.objects.all()

5 个答案:

答案 0 :(得分:1)

我认为有几个选择。两个最干净的将是:

  1. 为您的模型设置不同的端点。这对我来说就像是最RESTful的方法。
  2. 创建与您的其他模型相关的ForeignKey的VehicleModel。这应该适用于您编写的Serializer。
  3. 对于模型,第二种方法看起来像这样:

    # models.py
    class Vehicle(models.Model):
        pass
    
    class Truck(models.Model):
        vehicle = models.ForeignKey(Vehicle, related_name='trucks')
    
    ....
    

    对于观点来说就像这样:

    #views.py
    class VehiclesListView(generics.ListAPIView):
        queryset = Vehicle.objects.prefetch_related('cars', 'trucks', 'bikes').all()
        serializer_class = VehiclesSerializer
    

    关于prefetch_related()的注释:Django将使用四个数据库查询来获取对象,每个相关模型一个,主模型一个。如果您单独使用Vehicle.objects.all(),则序列化程序将为遇到的每个 Vehicle创建一个数据库请求。见Django docs here

    如果您不想这样做,您始终可以使用自定义逻辑覆盖ListAPIView.list,甚至可以完全绕过序列化程序:

    class VehiclesListView(generics.ListAPIView):
        def list(self, request, *args, **kwargs):
            cars = Cars.objects.values('id', 'name')
            trucks = Trucks.objects.values('id', 'name')
            bikes = Bikes.objects.values('id', 'name')
    
            out = {
                'trucks': trucks,
                'cars': cars,
                'bikes': bikes,
            }
            return Response(out)
    

    关于使用values()而不是all()的注意事项:您并没有真正使用序列化程序中的任何其他模型字段,因此查询额外字段没有用处。 Docs

答案 1 :(得分:0)

您应该真正阅读API Documentation

queryset = Vehicles.objects.all();

或获取随机的100或10个对象:

Vehicles.objects.all().order_by('?')[:100]

Vehicles.objects.all().order_by('?')[:10]

答案 2 :(得分:0)

queryset = Vehicles.objects.all()

或者,如果您需要过滤日期时间或请求属性。

def get_queryset(self):
    return Vehicles.objects.all()

答案 3 :(得分:0)

我得到的最好的是没有使用泛型:

class VehiclesListView(APIView):

def get(self, request, *args, **kwargs):
    ser = VehiclesSerializer({
        'cars': Car.objects.all(),
        'trucks': Truck.objects.all(),
        'bikes': Bike.objects.all()
    })

    return JsonResponse(ser.data)

感谢大家的帮助:)

答案 4 :(得分:0)

最简单的方法是使用DjangoRestMultipleModels

文档很漂亮。

在您的情况下,视图将如下所示:

from drf_multiple_model.views import MultipleModelAPIView

class VehicleView(MultipleModelAPIView):
    queryList = [
        (Car.objects.all(),CarSerializer),   #(queryset,Serializer)
        (Truck.objects.all(),TruckSerializer),
        (Bike.objects.all(), BikeSerializer),
]

希望这有助于某人..