【问题标题】:Serializer is displaying id instead of field names with Foreignkey序列化程序使用外键显示 id 而不是字段名称
【发布时间】:2021-06-19 01:38:28
【问题描述】:

我正在构建一个使用 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 打印查询集。它正确打印停止名称。 我在使用序列化程序时遇到了上述问题。

提前致谢!

【问题讨论】:

  • 可否添加序列化实例化的视图?
  • @KevinSmeeks 我已经添加了 views.py 代码

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


【解决方案1】:

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

其次是你的问题,首先你应该从BusSerializer中删除bus_in_route,并从BusStopSerializer中删除start_stopend_stop。如果您只想显示模型名称,也可以完全删除 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

【讨论】:

    猜你喜欢
    • 2020-08-19
    • 2015-05-08
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    • 2019-10-24
    • 2019-10-11
    • 2013-01-01
    • 1970-01-01
    相关资源
    最近更新 更多