序列化程序使用外键显示 id 而不是字段名称
Serializer is displaying id instead of field names with Foreignkey
我正在构建一个使用 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 形式的输出。子模型 (Bus
、BusStop
) 中的字段值将替换为其 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
打印查询集。它正确打印停止名称。
我在使用序列化器时遇到了上述问题。
提前致谢!
首先你应该注意给ForeignKey
字段的related_name
参数指的是它的模型而不是它的字段。
例如在 start_stop
字段中,它的 related_name
必须是 "start_routes"
或类似的东西。这意味着如果你有一个
BusStop
名为 stop_obj
的对象,您可以通过 stop_obj.start_routes.all()
.
访问从该站点开始的路线
其次,对于您的问题,首先您应该从 BusSerializer
中删除 bus_in_route
,并从 BusStopSerializer
中删除 start_stop
和 end_stop
。如果你只想显示模型名称,也可以完全删除 BusSerializer
和 BusStopSerializer
,然后将 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
我正在构建一个使用 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 形式的输出。子模型 (Bus
、BusStop
) 中的字段值将替换为其 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
打印查询集。它正确打印停止名称。
我在使用序列化器时遇到了上述问题。
提前致谢!
首先你应该注意给ForeignKey
字段的related_name
参数指的是它的模型而不是它的字段。
例如在 start_stop
字段中,它的 related_name
必须是 "start_routes"
或类似的东西。这意味着如果你有一个
BusStop
名为 stop_obj
的对象,您可以通过 stop_obj.start_routes.all()
.
访问从该站点开始的路线
其次,对于您的问题,首先您应该从 BusSerializer
中删除 bus_in_route
,并从 BusStopSerializer
中删除 start_stop
和 end_stop
。如果你只想显示模型名称,也可以完全删除 BusSerializer
和 BusStopSerializer
,然后将 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