简体   繁体   English

序列化程序使用外键显示 id 而不是字段名称

[英]Serializer is displaying id instead of field names with Foreignkey

I'm building a Django app which uses django rest framework and it shows the lists of buses in between two stops given by the user.我正在构建一个 Django 应用程序,它使用 django rest 框架,它显示了用户给出的两站之间的巴士列表。 For this purpose, I wanted to produce a json output as shown below.为此,我想制作一个 json output 如下所示。

   [
    {
        "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"
    }
]

But I'm getting the output in the form of IDs.但我得到的是 ID 形式的 output。 The field values in the child models ( Bus , BusStop ) are replaced with their IDs.子模型( 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
    }
]

Code: models.py代码: 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序列化程序.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视图.py

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

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

Is the usage of ForeignKey right? ForeignKey的使用正确吗? In my views.py , I've tried printing the queryset using start_stop__stop_name .在我的views.py中,我尝试使用start_stop__stop_name打印查询集。 It correctly prints the stop names.它正确打印停止名称。 I'm facing the mentioned problem when I'm using serializers.我在使用序列化程序时遇到了上述问题。

Thanks in advance!提前致谢!

First you should note that related_name parameter given to ForeignKey field refers to its Model not its field.首先你应该注意给ForeignKey字段的相关名称参数是指它的related_name而不是它的字段。
For example in start_stop field, its related_name must be "start_routes" or something like this.例如在start_stop字段中,它的related_name必须是"start_routes"或类似的东西。 It means that if you have an BusStop object named stop_obj , you can access routes that starts from this stop by stop_obj.start_routes.all() .这意味着如果您有一个名为BusStop的 BusStop stop_obj ,您可以通过stop_obj.start_routes.all()访问从该站点开始的路线。

Second for your problem, first you should remove bus_in_route from BusSerializer and also remove start_stop and end_stop from BusStopSerializer .其次,对于您的问题,首先您应该从BusStopSerializer中删除bus_in_route ,并从BusSerializer中删除start_stopend_stop If you want to show just name of models, also you can remove BusSerializer and BusStopSerializer entirely and then just convert BusRouteSerializer to this:如果您只想显示模型的名称,您也可以完全删除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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM