序列化程序显示 id 而不是带有外键

时间:2021-03-22 11:55:25

标签: python json django django-rest-framework django-serializer

我正在构建一个使用 django rest 框架的 Django 应用程序,它显示了用户给出的两个站点之间的总线列表。为此,我想生成如下所示的 json 输出。

   [
    {
        "id": 1,
        "start_time": "09:48:52",
        "end_time": "09:48:53",
        "start_stop": "A",
        "end_stop": "B",
        "bus_in_route": "Bus1"
    },
    {
        "id": 2,
        "start_time": "10:00:00",
        "end_time": "10:10:00",
        "start_stop": "B",
        "end_stop": "C",
        "bus_in_route": "Bus2"
    }
]

但我以 ID 的形式获得输出。子模型(BusBusStop)中的字段值将替换为其 ID。

[
    {
        "id": 1,
        "start_time": "09:48:52",
        "end_time": "09:48:53",
        "start_stop": 1,
        "end_stop": 2,
        "bus_in_route": 1
    },
    {
        "id": 2,
        "start_time": "10:00:00",
        "end_time": "10:10:00",
        "start_stop": 2,
        "end_stop": 3,
        "bus_in_route": 1
    }
]

代码: models.py

class BusStop(models.Model): # model to store several bus stops
    stop_name=models.CharField(max_length=255)
    def __str__(self):
        return str(self.stop_name)


class Bus(models.Model):  # model to store names of several buses
    bus_name=models.CharField(max_length=255)
    def __str__(self):
        return self.bus_name
    class Meta:
        verbose_name = 'Bus'
        verbose_name_plural = 'Buses'


class BusRoute(models.Model):  # lists out routes with start and end stops with the bus running between the stops
    start_stop = models.ForeignKey(BusStop,
                                related_name='start_stop',
                                on_delete=models.CASCADE)
    end_stop = models.ForeignKey(BusStop,
                                related_name='end_stop',
                                on_delete=models.CASCADE)
    bus_in_route = models.ForeignKey(Bus,
                                related_name='bus_in_route',
                                on_delete=models.CASCADE)
    start_time = models.TimeField()
    end_time = models.TimeField()

    def __str__(self):
        return str(self.start_stop)

serializers.py

class BusRouteSerializer(serializers.ModelSerializer):
    class Meta:
        model = BusRoute
        #fields=('firstname','lastname')
        fields='__all__'
        
class BusSerializer(serializers.ModelSerializer):
    bus_in_route = BusRouteSerializer(read_only=True,many=True)
    class Meta:
        model = Bus
        fields='__all__'

class BusStopSerializer(serializers.ModelSerializer):
    start_stop = BusRouteSerializer(read_only=True,many=True)
    end_stop = BusRouteSerializer(read_only=True,many=True)
    class Meta:
        model = BusStop
        fields='__all__'

views.py

class searchBusRoute(ListAPIView):
    serializer_class = BusRouteSerializer
    filter_backends = [SearchFilter, OrderingFilter]

    def get_queryset(self):
        queryset = BusRoute.objects.all()
        return queryset

ForeignKey 的用法对吗? 在我的 views.py 中,我尝试使用 start_stop__stop_name 打印查询集。它正确打印停止名称。 我在使用序列化程序时遇到了上述问题。

提前致谢!

1 个答案:

答案 0 :(得分:1)

首先,您应该注意,赋予 related_name 字段的 ForeignKey 参数是指其模型而不是其字段。
例如在 start_stop 字段中,它的 related_name 必须是 "start_routes" 或类似的东西。这意味着如果你有一个 BusStop 对象名为 stop_obj,您可以访问从 stop_obj.start_routes.all() 从该站开始的路线。

其次,对于您的问题,首先您应该从 bus_in_route 中删除 BusSerializer,并从 start_stop 中删除 end_stopBusStopSerializer。如果您只想显示模型名称,也可以完全删除 BusSerializerBusStopSerializer,然后将 BusRouteSerializer 转换为:


class BusRouteSerializer(serializers.ModelSerializer):

    start_stop = serializers.SerializerMethodField()
    end_stop = serializers.SerializerMethodField()
    bus_in_route = serializers.SerializerMethodField()
            
    class Meta:
        model = BusRoute
        fields = '__all__'
                
    def get_start_stop(self, obj):
        return obj.start_stop.stop_name
            
    def get_end_stop(self, obj):
        return obj.end_stop.stop_name
            
    def get_bus_in_route(self, obj):
        return obj.bus_in_route.bus_name