Django Rest Framework显示反向字段

时间:2018-03-20 12:41:16

标签: rest django-rest-framework

我的问题是围绕使用Django Rest Framework设计RESTful API。我有以下两个数据文件。

# cars.csv
Escalade, Ford
Outback, Subaru
Fiesta, Ford

# description.csv
new, "Escalade", 2018, "perfect condition"
used, "Escalade", 2016, "in good shape"
used, "Escalade", 2010, "bad condition"

我想要一个仅输出GET的API端点,它将输出以下内容:

{
  "model": "Escalade",
  "company": "Ford",
  "year": 2018,
  "details": [
    {
      "condition": "new",
      "description": "perfect condition"
    }
 ]

}

问题是如何显示year,使其从模型位置显示一个级别。如果我更改了原始的csv文件,我可以将年份添加到cars.csv但是假设我不能这样做。如何配置我的序列化程序以输出所需的API端点?

这是模型,序列化程序,视图和网址。

# models.py
from django.db import models

class Car(models.Model):
    model = models.CharField(max_length=100)
    company = models.CharField(max_length=100)

class Detail(models.Model):
    year = models.CharField(
    condition = models.CharField(max_length=100)    
    car = models.ForeignKey('Car', related_name='details',
                        on_delete=models.CASCADE,)
    description = models.CharField(max_length=100)


# serializers.py
from rest_framework import serializers
from . import models


class DetailSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        fields = ('year', 'condition', 'description',)
        model = models.Detail


class CarSerializer(serializers.HyperlinkedModelSerializer):
    details = DetailSerializer(many=True, read_only=True)

class Meta:
    fields = ('model', 'company', 'details',)
    model = models.Car

# views.py
from rest_framework import generics

from . import models
from . import serializers


class CarDetail(generics.RetrieveAPIView):
    queryset = models.Detail.objects.all()
    serializer_class = serializers.DetailSerializer


class CarList(generics.ListAPIView):
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarSerializer



# urls.py 
from django.urls import path

from . import views

urlpatterns = [
    path('', views.CarList.as_view()),
    path('<int:pk>', views.CarDetail.as_view()),
]

1 个答案:

答案 0 :(得分:0)

也许使用SerializerMethodField

class CarSerializer(serializers.HyperlinkedModelSerializer):
    details = DetailSerializer(many=True, read_only=True)
    year = serializers.SerializerMethodField()

    class Meta:
        fields = ('model', 'company', 'details', 'year',)
        model = models.Car

    def get_year(self, car):
        return car.details.first().year

你需要有点小心,因为上面的例子假设汽车总是至少有一个Detail,它将使用它找到的第一个。