有没有办法从 ModelViewSet 中的 RelatedManager 中过滤掉项目?

Is there a way to filter out items from RelatedManager in a 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/"
                },
    ...
}

完全没问题。但是 我真正想做的是 ,如果 Columnname=None,它会从每个 API ViewSet 中过滤掉。我已经通过 queryset = queryset.filter(name__isnull=False)ColumnViewSet 上做到了,但我不能对 TableViewSet 或其他可能显示 Column 列表的人做到这一点。

我试过修改 ColumnSerializer,但我能从中得到的最好结果是在 Column 列表中显示 nulls。

我想知道是否有隐藏这些的方法。

编辑 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 object [Django-doc] 来过滤相关对象集合,因此:

from django.db.models import <strong>Prefetch</strong>

class TableViewSet(viewsets.ModelViewSet):
    serializer_class = TableSerializer

    def get_queryset(self):
        queryset = Table.objects.prefetch_related(
            Prefetch('columns', <strong>Column.objects.filter(name__isnull=False)</strong>)
        ).order_by('name')
        # some query_params filtering
        return queryset