如何在 Django Rest Framework 中更改视图集检索响应?

mur*_*haA 1 django api-design django-views python-3.x django-rest-framework

我目前正在开发一个使用 API 作为大学项目后端的 Web 应用程序。

我已经读过 DRF 是开发和部署 API 的最快和最简单的方法,我已经遵循了他们的整个官方

文档,我似乎不明白我如何在他们的 ViewSet 和 Serializer 中进行以下操作。

这是我的 API 的一个端点,称为机场。

美国的所有机场

返回指向美国可用机场的链接的 json/csv 列表。

  • 网址

    /airports

  • 方法:

    GET

  • 成功响应:

    • 代码: 200
      内容:

      [
        {
            "airport": {
                "code": "PHL",
                "name": "Philadelphia, PA: Philadelphia International",
              "id": 123,
                "url": "/airports/123"
            },
        {
            "airport": {
                "code": "AHR",
                "name": "American Hour Rapid",
            "id": 125,
                "url": "/airports/125"
        }
        .
        .
        .
      ]
    
    Run Code Online (Sandbox Code Playgroud)

显示机场信息

返回指向在特定机场运营的航空公司的所有链接、指向特定月份和年份的相关统计数据的链接以及指向机场航线的链接。如果既未指定年份也未指定月份,则默认为具有最近日期的日期。

  • 网址

/airports/:id

  • 方法:

GET

  • 网址参数

    必需的:

    id=[integer]

  • 成功响应:

{
    "airport": {
      "code": "PHL",
      "name": "Philadelphia, PA: Philadelphia International",
      "id": 123,
      "url": "/airports/123"
    },
    "routes_link": "/airports/123/routes",
    "carriers": [
        {
          "id": 124,
          "url": "/carriers/124?airport_id=123",
          "statistics_url":"/airports/1carrier=124&statistics='flights'"
        },
        .
        .
        .
      ]
}
Run Code Online (Sandbox Code Playgroud)

我能够 /airports 正确地列出数据库中所有可用的机场,但是在使用 ViewSet 时,我不知道如何在尝试检索有关仅由 id 指定的一个机场的信息时“自定义”响应,并在应用程序将动态生成路由,我计划添加到响应正文而不是模型中的另一个字段。

楷模:

class Carrier(models.Model):
    code = models.CharField(max_length=10)
    name = models.TextField()
    #airports = models.ManyToManyField(Airport) 

    def __str__(self):
        return self.name

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
Run Code Online (Sandbox Code Playgroud)

序列化器:

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

class CarrierSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = models.Carrier
        fields = ('id', 'name', 'code', 'url')
Run Code Online (Sandbox Code Playgroud)

看法:

class AirportList(viewsets.ModelViewSet):
    queryset = models.Airport.objects.all()
    serializer_class = AirportSerializer
    # @Override something here?
Run Code Online (Sandbox Code Playgroud)

任何人都有关于如何使用 DRF 或我可以使用的任何类型的学习材料来解决这个问题的提示?

Sha*_*kil 6

如果你想修改retrieveModelViewset 的功能,你可以覆盖它的retrieve方法并做任何你想做的事情。mixin's 关联

class AirportList(viewsets.ModelViewSet):
    queryset = models.Airport.objects.all()
    serializer_class = AirportSerializer
    def retrieve(self, request, *args, **kwargs):
        # do your customization here
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response(serializer.data)
Run Code Online (Sandbox Code Playgroud)

如何探索 DRF

我认为照顾任何新事物的最佳方法是他们的代码库。对于 ModelViewset,您应该从views链接开始并探索它提供的功能以及如何自定义它们。

  • 覆盖检索对我不起作用,即使在修改它之后我也得到相同的响应,即使我返回“Hello”。 (2认同)