DJango rest framework - список API с использованием поля фильтра из связанных моделей

Здравствуйте, я новичок в Django и фреймворке Django rest, поэтому моя терминология может быть ошибочной.

Я пытаюсь создать API, который возвращает список элементов из модели, но отфильтрованный на основе полей другой связанной модели.

Я предоставлю свои текущие классы представления и сериализатора, а также модели

class service(models.Model):
    name = models.CharField(max_length=50)
    vendor = models.CharField(max_length=50)
    version = models.CharField(max_length=10)
    registration_status = models.BooleanField(default=False)

class service_network(models.Model):

    service = models.OneToOneField(
        service,
        related_name='network',
        on_delete=models.CASCADE,
        primary_key=True,
    )
    forwarded_port = models.CharField(max_length=50)

class ServiceNetworkSerializer(serializers.ModelSerializer):
    class Meta:
        model = service_network
        fields = '__all__'

class ServiceSerializer(serializers.ModelSerializer):
    network = ServiceNetworkSerializer()

    class Meta:
        model = service
        fields = [
            'id',
            'name',
            'vendor',
            'version',
            'registration_status',
            'network',
        ]
class ServiceAPI(ModelViewSet):
    queryset = service.objects.all()
    serializer_class = ServiceSerializer
    filterset_fields = '__all__'

В настоящее время я могу получить списки, используя строку запроса URL

{{baseUrl}}/engine/service?registration_status=true

Что я хочу сделать, это что-то вроде этого

{{baseUrl}}/engine/service/network?forwarded_port=8080

Я бы ожидал получить список сервисов, где связанное сетевое поле "forwarded_port" равно 8080.

Есть ли другой способ запросить этот API? Может быть, используя POST с телом, содержащим запрос? Если есть что-то в DOCS, что я могу прочитать, я пытался просмотреть фильтрацию и наборы запросов, но я не смог найти ничего, что могло бы сделать это из коробки

Я тоже новичок на stackoverflow и постарался сделать свой вопрос кратким и с максимальным количеством нужной информации, так что если чего-то не хватает, я буду рад отредактировать свой вопрос

Попробуйте это:

{{baseUrl}}/engine/service?network__forwarded_port=8080

Возможно, это работает.

Док: https://docs.djangoproject.com/en/dev/topics/db/queries/#lookups-that-span-relationships-1

РЕДАКТИРОВАНИЕ:

Если ответ выше не работает, вы можете изменить класс ServiceApi и фильтровать самостоятельно:

class ServiceAPI(ModelViewSet):
    def get_queryset(self):
        if self.request.GET.get(network__forwarded_port)
            return service.objects.filter(network__forwarded_port = self.request.GET.get(network__forwarded_port))
        else:
            return service.objects.all()
    serializer_class = ServiceSerializer
    filterset_fields = '__all__'

Я смог решить эту проблему, используя следующий queryset override

    def get_queryset(self):
    if len(self.request.GET) > 0:
        query_set = {}
        for query in self.request.GET:
            query_set[query] = self.request.GET.get(query)
        return service.objects.filter(**query_set)
    else:
        return service.objects.all()

Это позволяет вам фильтровать поля без явного указания того, что это такое, в случаях, когда у вас много полей, которые нужно фильтровать. Я также должен сказать, что поскольку у меня нет опыта работы с Django, я не уверен, какие ошибки это может вызвать, но это хак, который сработал для меня. Если я обнаружу, что это действительно плохо, я вернусь и удалю это.

Вернуться на верх