Есть ли способ отфильтровать элементы из RelatedManager в ModelViewSet?

Я использую DRF для простого API, и мне интересно, есть ли способ добиться такого поведения:

  • У меня есть две модели, похожие на следующие:
class Table(models.Model):
    name = models.CharField(max_length=100)
    ...

class Column(models.Model):
    original_name = models.CharField(max_length=100)
    name = models.CharField(max_length=100, blank=True, null=True)
    ...
    table = models.ForeignKey(Table, on_delete=models.CASCADE, related_name="columns")
  • И их сериализаторы следующим образом:
class ColumnSerializer(serializers.HyperlinkedModelSerializer):
    table = serializers.HyperlinkedRelatedField(
        read_only=True, view_name="table-detail"
    )

    class Meta:
        model = Column
        fields = ["url", "name", "table"]

class TableSerializer(serializers.HyperlinkedModelSerializer):
    dataset = serializers.HyperlinkedRelatedField(
        read_only=True, view_name="dataset-detail"
    )
    tags = serializers.SlugRelatedField(
        many=True, slug_field="name", queryset=Tag.objects.all()
    )
    columns = ColumnSerializer(many=True, read_only=True)

    class Meta:
        model = Table
        fields = [
            "url",
            "name",
            ...
            "columns",
        ]
  • Это дает результат, аналогичный
{
    ...
    "results": [
        {
            "url": "http://0.0.0.0:8001/api/tables/1/",
            "name": "some-name",
            "columns": [
                {
                    "url": "http://0.0.0.0:8001/api/columns/1/",
                    "name": "id",
                    "table": "http://0.0.0.0:8001/api/tables/1/"
                },
    ...
}

что совершенно нормально. Но что я действительно хотел бы сделать, так это , если Column имеет name=None, то он отфильтровывается из каждого API ViewSet. Мне удалось сделать это для ColumnViewSet, сделав queryset = queryset.filter(name__isnull=False), но я не могу сделать это для TableViewSet или других, которые могут показать Column список.

Я пробовал возиться с ColumnSerializer, но лучшее, чего я смог добиться, это отображение null в списке Column.

Интересно, есть ли способ скрыть их.

РЕДАКТИРОВАНИЕ 1: Добавление моих наборов представлений

class TableViewSet(viewsets.ModelViewSet):
    serializer_class = TableSerializer

    def get_queryset(self):
        queryset = Table.objects.all().order_by("name")
        # some query_params filtering
        return queryset

class ColumnViewSet(viewsets.ModelViewSet):
    serializer_class = ColumnSerializer

    def get_queryset(self):
        queryset = Column.objects.all().order_by("id")
        queryset = queryset.filter(name__isnull=False)
        # some query_params filtering
        return queryset

Вы можете работать с Prefetch объектом [Django-doc] для фильтрации коллекции связанных объектов, так:

from django.db.models import Prefetch

class TableViewSet(viewsets.ModelViewSet):
    serializer_class = TableSerializer

    def get_queryset(self):
        queryset = Table.objects.prefetch_related(
            Prefetch('columns', Column.objects.filter(name__isnull=False))
        ).order_by('name')
        # some query_params filtering
        return queryset
Вернуться на верх