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

Gab*_*lan 4 python django django-rest-framework

我使用 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")
Run Code Online (Sandbox Code Playgroud)
  • 他们的序列化器如下:
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",
        ]
Run Code Online (Sandbox Code Playgroud)
  • 这会返回类似于以下内容的输出
{
    ...
    "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/"
                },
    ...
}

Run Code Online (Sandbox Code Playgroud)

这完全没问题。但我真正想做的是,如果 aColumnname=None,它就会从每个 API ViewSet 中过滤掉。我已经设法通过 do 来做到这一点ColumnViewSetqueryset = queryset.filter(name__isnull=False)但我无法为TableViewSet或其他可能显示Column列表的人做到这一点。

我尝试过修改ColumnSerializer,但我能从中得到的最好的结果就是null在列表中显示 s 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
Run Code Online (Sandbox Code Playgroud)

Wil*_*sem 5

您可以使用Prefetchobject\xc2\xa0 [Django-doc]来过滤相关的对象集合,因此:

\n
from django.db.models import Prefetch\n\nclass TableViewSet(viewsets.ModelViewSet):\n    serializer_class = TableSerializer\n\n    def get_queryset(self):\n        queryset = Table.objects.prefetch_related(\n            Prefetch(\'columns\', Column.objects.filter(name__isnull=False))\n        ).order_by(\'name\')\n        # some query_params filtering\n        return queryset
Run Code Online (Sandbox Code Playgroud)\n