【问题标题】:DRF Response returning all fields when using queryset method only仅在使用查询集方法时返回所有字段的 DRF 响应
【发布时间】:2019-08-05 05:42:08
【问题描述】:

我正在做一个大学项目,需要我使用 API 作为后端来实现一个 Web 应用程序,我决定使用 DRF 来完成它,但我现在遇到了一些麻烦。

我正在尝试覆盖 View 中的 list 方法,以便在检索所有机场记录的列表时仅显示一些字段,但在响应中仍然返回所有字段。

型号:

class Airport(models.Model):
    code = models.CharField(max_length=10)
    name = models.TextField()
    carriers = models.ManyToManyField(Carrier, related_name='airports')

    def __str__(self):
        return self.name

序列化器:

class AirportSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = models.Airport
        fields = ('id', 'name', 'code', 'url', 'carriers')

查看:

class AirportView(viewsets.ModelViewSet):
    queryset = models.Airport.objects.all()
    serializer_class = AirportSerializer

    def list(self, request):
        airports = models.Airport.objects.only('id', 'name', 'code')
        data = AirportSerializer(airports, many=True, context={'request': request}).data
        return Response(data)

回复:

{
        "id": 4,
        "name": "Leo",
        "code": "Test",
        "url": "http://localhost:8000/api/airports/4/",
        "carriers": []
    },
    {
        "id": 5,
        "name": "asdasd",
        "code": "aasdasd",
        "url": "http://localhost:8000/api/airports/5/",
        "carriers": [
            "http://localhost:8000/api/carriers/1/"
        ]
    },
    {
        "id": 6,
        "name": "asdasd",
        "code": "aasdasd",
        "url": "http://localhost:8000/api/airports/6/",
        "carriers": [
            "http://localhost:8000/api/carriers/1/"
        ]
    }

我该如何解决这个问题? 有没有更好的方法,我的意思是不使用 QuerySet.only 方法?

【问题讨论】:

标签: django python-3.x django-rest-framework django-views django-serializer


【解决方案1】:

只需像这样将想要的字段放入您的序列化程序中:

class AirportSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
     model = models.Airport
    fields = ('id', 'name', 'code')

你可以走了。

【讨论】:

  • 查询是只在某些情况下使用选择性字段(列表)。
【解决方案2】:

定义对象如何序列化的是序列化程序,而不是您如何过滤数据库中的数据。目前,您在序列化程序中拥有所有可用字段。如果您不希望在列出或检索项目时返回某些字段,您可以在序列化程序中将这些字段定义为 write_only,如下所示:

class AirportSerializer(serializers.HyperlinkedModelSerializer):
    url = serializer.CharField(write_only=True)
    carriers = serializer.PrimaryKeyRelatedField(many=True, write_only=True)

    class Meta:
        model = models.Airport
        fields = ('id', 'name', 'code', 'url', 'carriers')

这样,url和carriers字段在返回数据时不会出现,但在插入数据时是必需的。

【讨论】:

    【解决方案3】:

    您应该定义一个单独的序列化程序并返回它。

    【讨论】:

    • 但是为什么 QuerySet 中有 only() 方法呢?
    • 奇怪的问题。当您只想检索查询集中的某些元素时,它就在那里。但是查询集不控制 DRF 响应中返回的内容,这是序列化程序的工作。
    • 哦,现在对我来说,查询集只适用于模型和数据库记录,序列化程序只是验证内容,谢谢:)。
    猜你喜欢
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-06
    • 2018-10-04
    • 2016-10-09
    • 2013-03-30
    相关资源
    最近更新 更多