Я хочу получить несколько моделей за один запрос, поэтому получу:

{
  "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

Но, как вы видите, мне не удалось понять, как написать набор запросов.

Любая помощь?

ОБНОВИТЬ:

Просто чтобы уточнить мой вопрос. Там нет модели транспортного средства. Вот почему я НЕ пишу регулярные queryset = Vehicles.objects.all()

0
Guy Segev 15 Дек 2015 в 19:17

5 ответов

Лучший ответ

Лучшее, что я получил, было без использования дженериков:

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)

Спасибо всем за помощь :)

0
Guy Segev 16 Дек 2015 в 09:55

Самый простой способ - использовать 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),
]

Надеюсь, это кому-то поможет ..

0
Venkatesh Mondi 17 Июл 2016 в 17:50

Я думаю, что есть несколько вариантов. Два самых чистых были бы:

  1. Иметь разные конечные точки для ваших моделей. Это похоже на самый RESTful подход ко мне.
  2. Создайте VehicleModel, который ForeignKey связан с вашими другими моделями. Это должно даже работать с Сериализатором, который вы написали.

Второй подход будет выглядеть примерно так для моделей:

# 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 здесь.

Если вы не хотите этого делать, вы всегда можете переопределить 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(): вы на самом деле не используете никакие другие поля модели в вашем сериализаторе, поэтому нет смысла запрашивать дополнительные поля. Документы

1
Geotob 15 Дек 2015 в 21:26

Вам действительно следует прочитать документацию API.

Queryset = Vehicles.objects.all ();

Или получить случайные 100 или 10 объектов:

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

Или

Vehicles.objects.all().order_by('?')[:10]
0
Jay Geeth 15 Дек 2015 в 16:25
queryset = Vehicles.objects.all()

Или если вам нужно отфильтровать по дате или времени запроса свойств.

def get_queryset(self):
    return Vehicles.objects.all()
0
Sander van Leeuwen 15 Дек 2015 в 16:30