我将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/"
                },
    ...
}

这很好.但是what I'd really want to do is,如果Columnname=None,那么它会从每个API视图集中过滤掉.我已经通过queryset = queryset.filter(name__isnull=False)做到了ColumnViewSet,但对于TableViewSet或其他可能显示Column的列表,我无法做到.

我try 过修补ColumnSerializer个,但我能从中得到的最好结果是在Column个列表中显示null个.

我想知道有没有办法把这些藏起来.

EDIT 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 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

Python相关问答推荐

是否有方法将现有的X-Y图转换为X-Y-Y1图(以重新填充)?

定义同侪组并计算同侪组分析

自定义新元未更新参数

是什么导致对Python脚本的jQuery Ajax调用引发500错误?

Python panda拆分列保持连续多行

LAB中的增强数组

Python会扔掉未使用的表情吗?

即使在可见的情况下也不相互作用

大小为M的第N位_计数(或人口计数)的公式

如何在python xsModel库中定义一个可选[December]字段,以产生受约束的SON模式

如何过滤包含2个指定子字符串的收件箱列名?

将输入聚合到统一词典中

使用NeuralProphet绘制置信区间时出错

为什么Django管理页面和我的页面的其他CSS文件和图片都找不到?'

isinstance()在使用dill.dump和dill.load后,对列表中包含的对象失败

Django admin Csrf令牌未设置

在pandas数据框中计算相对体积比指标,并添加指标值作为新列

lityter不让我输入左边的方括号,'

如何在Python请求中组合多个适配器?

Beautifulsoup:遍历一个列表,从a到z,并解析数据,以便将其存储在pdf中.