有没有一种方法可以在ModelViewSet中从RelatedManager过滤掉项目?

4

我将使用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上实现了这一点,但我无法在可能显示Column列表的TableViewSet或其他视图集上实现。

我已经尝试过调整ColumnSerializer,但最好的结果只能在Column列表上显示null

我想知道是否有一种方法可以隐藏它们。

编辑1:添加我的ViewSets

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
1个回答

5

您可以使用Prefetch对象[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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接