Фильтровать связанные объекты Django - PullRequest
0 голосов
/ 10 сентября 2018

Представьте себе такие модели в Джанго:

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 необходимо выполнить конечную точку для

  • список всех организаций
  • всех гостей в списке
  • заказы будут отфильтрованы против start_date и перечислены

Образец ответа:

"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 голосов
/ 10 сентября 2018

Похоже, этот подход с использованием 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
...