Django Rest Framework - как получить только одно поле из набора связанных моделей - PullRequest
1 голос
/ 23 сентября 2019

У меня есть следующие модели:

from django.db import models

class City(models.Model):
    name = models.CharField(max_length=30)
    last_update = models.DateTimeField(null=True)

class BusStop(models.Model):
    city = models.ForeignKey(City, on_delete=models.CASCADE)
    name = models.CharField(max_length=200, blank=True, default='')

Теперь, используя Django Rest Framework, я хотел бы создать сериализатор, который будет возвращать сведения о городе вместе со списком всех BusStops в городе - но я хочу этот списокбыть только строками с именами BusStop, например:

{
  "id": 1
  "name": "City"
  "last_update": "2019-09-19T22:13:54.851363Z"
  "bus_stops": [
    "stop1",
    "stop2",
    "stop3"
  ]
}

До сих пор я пробовал следующие сериализаторы:

from rest_framework import serializers

class BusStopSerializer(serializers.ModelSerializer):
    class Meta:
        model = BusStop
        fields = ('name', )


class CityDetailsSerializer(serializers.ModelSerializer):
    busstop_set = BusStopSerializer(many=True)

    class Meta:
        model = City
        fields = ('id', 'name', 'last_update', 'busstop_set')

Но это создает список объектов с именем 'name'в них.Итак, как мне создать список, содержащий только BusStop имен (в виде строк)?

Ответы [ 2 ]

4 голосов
/ 23 сентября 2019

Вместо дополнительных BusStopSerializer вы можете использовать StringRelatedField :

# models.py
class BusStop(models.Model):
    city = models.ForeignKey(City, on_delete=models.CASCADE)
    name = models.CharField(max_length=200, blank=True, default='')

    def __str__(self):
        return self.name

# serializers.py
class CityDetailsSerializer(serializers.ModelSerializer):
    bus_stops = StringRelatedField(many=True)

    class Meta:
        model = City
        fields = ('id', 'name', 'last_update', 'bus_stops')
1 голос
/ 23 сентября 2019

StringRelatedField, как рекомендует wfehr, будет работать только до тех пор, пока метод BusStop __str__ возвращает только имя.Альтернативой является использование SlugRelatedField, который позволяет вам указать конкретное поле из связанной модели и не зависит от __str__.

bus_stops = SlugRelatedField(many=True, slug_field='name')
...