过滤相关对象Django

时间:2018-09-10 10:27:59

标签: django django-models django-rest-framework django-filter

想象一下Django中的此类模型:

class Organisation(Model):
    ...

class Guest(Model):
    organisation = ForeignKey(Guest, CASCADE, 'guests')

class Booking(Model):
    guest = ForeignKey(Guest, CASCADE, 'bookings')
    start_date = DateField()
    end_date = DateField()

使用Django Rest Framework时需要执行端点

  • 所有要列出的组织
  • 所有要列出的来宾
  • 要重新过滤的预订从开始日期开始并列出

回复样本:

"Organizations": [
    {
        ...,
        "Guests": [
            {
                ...,
                "Bookings": [
                     {...},
                     {...}
                ]
            },
            {
                ...,
                "Bookings": [
                ]
            }
        ]
    },
    {
        ...,
        "Guests": [
            {
                ...,
                "Bookings": [
                     {...},
                ]
            },
        ]
    }
]

因此,如您所见,我需要所有组织和来宾出席,而不仅仅是那些有预订的组织。

执行此操作的最佳方法是什么?

UPD:

使用的序列化器:

class BookingShortSerializer(serializers.ModelSerializer):
    class Meta:
        model = Booking
        fields = (
            'pk',
            'start_date',
            'guest',
        )


class GuestBookingsSerializer(serializers.ModelSerializer):
    bookings = BookingShortSerializer(many=True)

    class Meta:
        model = Guest
        fields = (
            'pk',
            'name',
            'bookings',
        )


class OrganizationShortSerializer(serializers.ModelSerializer):
    guests = GuestBookingsSerializer(many=True)

    class Meta:
        model = Organization
        fields = (
            'pk',

            'public_name',
            'internal_name',

            'guests',

            'order',
        )

使用了ViewSet(现在不进行过滤):

class OrganizationBookingsViewSet(mixins.ListModelMixin, GenericViewSet):
    ordering = 'order'

    serializer_class = OrganizationShortSerializer

    permission_classes = (AllowAny,)

    def get_queryset(self) -> QuerySet:
        return Organization.objects.all()

1 个答案:

答案 0 :(得分:0)

类似于使用 SerializerMethodField 的方法来解决任务。应该认为它是一个好的解决方案吗?

class GuestBookingsSerializer(serializers.ModelSerializer):
    bookings = serializers.SerializerMethodField()

    class Meta:
        model = Guest
        fields = (
            'pk',
            'name',
            'bookings',
        )

    def get_bookings(self, guest):
        date = self.context.['request'].query_params['start_date__gte']
        bookings = guest.bookings.filter(start_date__gte=date).all()
        serializer = BookingShortSerializer(bookings, many=True)
        return serializer.data