在Django中只预取一个/最新的对象

时间:2017-09-14 16:37:02

标签: django django-rest-framework

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__'

相关日志:

 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'

有没有办法通过Prefetch抓住最新的对象?假设我正在尝试提供所有有效和预留的租金,但我只想在州退回(最新)的情况下租一个租房?我将如何实现这一目标?

编辑: 对于任何关心的人 - 我通过使用SerializerMethodField并通过python对预取查询(通过属性租赁)进行排序来解决这个问题,以避免额外的数据库命中。不幸的是,prefetch只接受一个查询集而不是一个项目。

0 个答案:

没有答案