Reputation: 131
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. For this purpose, I wanted to produce a json output as shown below.
[
{
"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. The field values in the child models (Bus
, BusStop
) are replaced with their IDs.
[
{
"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
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
Is the usage of ForeignKey right?
In my views.py
, I've tried printing the queryset using start_stop__stop_name
. It correctly prints the stop names.
I'm facing the mentioned problem when I'm using serializers.
Thanks in advance!
Upvotes: 0
Views: 752
Reputation: 396
First you should note that related_name
parameter given to ForeignKey
field refers to its Model not its field.
For example in start_stop
field, its related_name
must be "start_routes"
or something like this. 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()
.
Second for your problem, first you should remove bus_in_route
from BusSerializer
and also remove start_stop
and end_stop
from BusStopSerializer
. If you want to show just name of models, also you can remove BusSerializer
and BusStopSerializer
entirely and then just convert BusRouteSerializer
to this:
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
Upvotes: 1