Как отфильтровать отношения по их полям в ответ, используя Django REST Framework - PullRequest
0 голосов
/ 12 января 2020

У меня три модели: Дом, Резидент, Автомобиль. В каждом доме много жителей (от одного до многих). Каждый житель имеет 0 или 1 автомобиль (один на один). Для моего интерфейса я хочу показать всех жителей дома, у которого есть машина. Django Rest Framework предлагает использовать фильтрацию, но это работает только на верхнем уровне. Например, в моем HouseDetailView(generics.RetrieveAPIView) я могу изменить только набор запросов самой модели Дома. Я хочу иметь возможность изменять набор запросов Resident (resident_queryset.exclude(car=None)).

class HouseDetailView(generics.RetrieveAPIView):
  queryset = House.objects.all()
  serializer_class = HouseSerializer

Можно / нужно ли сделать все это в одном запросе? Являются ли параметры запроса моим единственным способом фильтрации?

Ответы [ 2 ]

1 голос
/ 12 января 2020

Вы можете использовать Prefetch для фильтрации связанных объектов:

from django.db.models import Prefetch

class HouseDetailView(generics.RetrieveAPIView):
  serializer_class = HouseSerializer

  def get_queryset(self):
      return House.objects.prefetch_related(Prefetch('resident_set', queryset=Resident.objects.exclude(car__isnull=True)))

Примечание resident_set - обратное имя для Resident модели и может отличаться для вас, основываясь на related_name аргумент.

1 голос
/ 12 января 2020
# If you want to display all the residents of a house that have a car, then you should query the car model


class CarDetailView(generics.RetrieveAPIView):
    queryset = Car.objects.all()
    serializer_class = CarSerializer


serializers.py

class CarSerializer(serializers.ModelSerializer):

    # get the resident details (name)
    resident_name = serializers.SerializerMethodField('get_resident_name')

    def get_resident_name(self, obj):
        return obj.resident.name


    class Meta:
        model = Car
        fields = ("name", "resident_name")
...