Фреймворк Django REST, Сериализаторы: Дополнительные данные?

#python #django #serialization #django-rest-framework #request

Вопрос:

Хороший день,

Я хотел бы спросить, есть ли возможность получить дополнительные данные внутри моих сериализаторов? Это мои модели…

models.py

 class Chair(models.Model):
    name = models.CharField(max_length=100, null=False, blank=False, unique=True)
    bookable = models.BooleanField(default=False)
    user_created = models.CharField(max_length=100)
    date_created = models.DateField(auto_now_add=True)

class Booking(models.Model):
    chair = models.ForeignKey(Chair, on_delete=models.CASCADE)
    day = models.DateField()
    user_name = models.CharField(max_length=100)
    user_created = models.CharField(max_length=100)
    date_created = models.DateField(auto_now_add=True)
 

и эти мои сериализаторы…

serializers.py

 class BookingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Booking
        fields = '__all__'


class ChairSerializer(serializers.ModelSerializer):
    class Meta:
        model = Chair
        fields = '__all__'
 

При выполнении запроса внутри js, как это…

views.py

 @api_view(['GET'])
def bookings_by_date(request, pk):
    bookings = Booking.objects.filter(day=pk)
    serializer = BookingSerializer(bookings, many=True)
    return Response(serializer.data)
 

script.js

 let url = '...here's my url for Booking...';

fetch(url)
.then((resp) => resp.json())
.then(function(data) {
    // do something here
});
 

…Я хотел бы получить не только идентификатор кресла (модели.Иностранный ключ), но также и его название. Моей первой мыслью было сделать что-то подобное…

 class ChairSerializer(serializers.ModelSerializer):
    class Meta:
        model = Chair
        fields = [
            ...
            'chair',
            'chair__name',
            ...
            ]
 

…но это, похоже, не работает! Кто-нибудь знает решение моей проблемы? Спасибо за всю вашу помощь и желаю вам отличных выходных!

Ответ №1:

Вы можете использовать один из этих двух способов:

1-) Использование поля сериализатора. Таким образом, вы можете добавлять поля только для чтения. Вы должны добавить get_<field_name> метод или указать имя метода, которое вы хотите запустить для этого поля с ключевым словом name. Вы можете просмотреть документ для получения более подробной информации.

 class BookingSerializer(serializers.ModelSerializer):
    chair__name = serializers.SerializerMethodField()

    class Meta:
        model = Booking
        fields = '__all__'

    def get_chair_name(self, obj):
        return obj.chair.name
 

2-) Использование поля символов с атрибутом источника:
Вы можете в основном определить, откуда заполняется это поле.

  class BookingSerializer(serializers.ModelSerializer):
    chair__name = serializers.CharField(source='chair__name')

    class Meta:
        model = Booking
        fields = '__all__'