serialzer
class DriverSerializer(QueryFieldsMixin, serializers.ModelSerializer):
notes = DriverNoteSerializer(many=True, read_only=True)
rentals = DriverRentalSerializer(many=True, read_only=True)
latest_returned_rentals = DriverRentalSerializer(read_only=True)
class Meta:
model = Driver
fields = '__all__'
@staticmethod
def setup_eager_loading(queryset):
""" Perform necessary eager loading of data. """
# Prefetch for subsets of relationships
# latest_returned_rental =
queryset = queryset.prefetch_related(
Prefetch('drivernote_set',
queryset=DriverNote.objects.filter(driver_id__in=queryset).order_by('-date_created')
.select_related('owner'), to_attr='notes'),
Prefetch('rental_set',
queryset=Rental.objects.filter(state__in=['active', 'reserved'], driver_id__in=queryset).select_related('vehicle').select_related('driver'), to_attr='rentals'),
Prefetch('rental_set',
queryset=Rental.objects.filter(state='returned', driver_id__in=queryset).select_related('vehicle').select_related(
'driver')[0], to_attr='latest_returned_rentals')
)
return queryset
view
class DriverListView(LoggingMixin, ListCreateAPIView):
"""
get:
Return a list of all the existing drivers.
post:
Create a new driver instance.
"""
logging_methods = ['POST']
serializer_class = DriverSerializer
filter_backends = (OrderingFilter, SearchFilter, DjangoFilterBackend)
# filter_fields = ('driver_state', 'first_name', 'last_name')
filter_class = DriverFieldsFilter
# Add others once discussed
search_fields = ('first_name', 'last_name', )
ordering_fields = '__all__'
Relevant logs:
File "C:\Users\Borko\envs\sally-env\lib\site-packages\rest_framework\mixins.py", line 40, in list
queryset = self.filter_queryset(self.get_queryset())
File "C:\Users\Borko\PycharmProjects\ops4\drivers\views.py", line 40, in get_queryset
queryset = self.get_serializer_class().setup_eager_loading(queryset)
File "C:\Users\Borko\PycharmProjects\ops4\drivers\serializers.py", line 49, in setup_eager_loading
'driver')[0], to_attr='latest_returned_rentals')
AttributeError at /api/drivers/
'Rental' object has no attribute '_iterable_class'
Is there any way to grab just the latest object via Prefetch? Let's say I'm trying to pull in all active and reserved rentals, but I only want to pull one rental with state returned (latest)? How would I go about accomplishing that?
EDIT:
For anyone that cares - I solved this by using SerializerMethodField and sorting through the prefetched query (via attribute rentals) there via python to avoid additional DB hits. Unfortunately prefetch accepts only a queryset not an item.