[Fixed]-Django DRF multi model view

0👍

The best that I’ve got was without using generics:

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)

Thanks all for your help 🙂

1👍

There are a few options I think. The two cleanest ones would be:

  1. Have different endpoints for your models. This feels like the most RESTful approach to me.
  2. Create a VehicleModel that is ForeignKey related to your other models. That should even work with the Serializer you have written.

The 2nd approach would look something like this for the models:

# models.py
class Vehicle(models.Model):
    pass

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

....

And like this for the views:

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

Note on the prefetch_related() in there: Django will use four DB queries to get your objects, one for each related model and one for the main model. If you use Vehicle.objects.all() by itself, the Serializer will create a DB requests for every Vehicle it encounters. See Django docs here

If you don’t want to do that, you can always override ListAPIView.list with your custom logic, even bypass the serializer completely:

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)

Note on using values() instead of all(): You don’t really use any other model fields in your serializer, so there’s no use in querying extra fields. Docs

👤Geotob

0👍

You should really read the API Documentation.

queryset = Vehicles.objects.all();

or to get random 100 or 10 objects:

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

or

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

0👍

queryset = Vehicles.objects.all()

Or if you need to filter on datetime or request properties.

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

0👍

The easiest way is to use DjangoRestMultipleModels

The documentation is beautiful.

In your case the view would look like this:

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

Hope this helps someone..

Leave a comment