DjangoRestFramework и Javascript: извлечение дополнительных данных

#javascript #serialization #django-rest-framework #model #fetch

#javascript #сериализация #django-rest-framework #Модель #извлечение

Вопрос:

Я хотел бы спросить, возможно ли создать ответ со связанными данными из второй модели? Например:

models.py

 class Manufacturer(models.Model):
    name = models.CharField(max_length=100, null=False, blank=False, unique=True)
    date_created = models.DateTimeField(auto_now_add=True)

class Car(models.Model):
    manufacturer = models.ForeignKey(Manufacturer, null=False, blank=False, on_delete=models.CASCADE)
    name = models.CharField(max_length=100, null=False, blank=False)
    date_created = models.DateTimeField(auto_now_add=True)
 

serializers.py

 class ManufacturerSerializer(ModelSerializer):
    class Meta:
        model = Manufacturer
        exclude = [
            'date_created',
        ]

class CarSerializer(ModelSerializer):
    class Meta:
        model = Car
        exclude = [
            'date_created',
        ]
 

views.py

 @api_view(['GET'])
def api_list_manufacturer(request):
    qs = Manufacturer.objects.all()
    serializer = ManufacturerSerializer(qs, many=True)
    return Response(serializer.data)

@api_view(['GET'])
def api_list_card(request):
    qs = Car.objects.all()
    serializer = CarSerializer(qs, many=True)
    return Response(serializer.data)
 

Правильно знаю, что я использую метод выборки для получения данных для автомобиля

 fetch(url)
.then(response => response.json)
.then(function(data) {
    console.log(data);
});
 

… и данные выглядят так:

 0: {id: 1, name: 'Focus', manufacturer: 1},
1: {id: 2, name: 'F-150', manufacturer: 1},
2: {id: 3, name: 'Model S', manufacturer: 2}
 

Мой вопрос:

Возможно ли получить, например, имя производителя в моем ответе? Что-то вроде этого?

 0: {id: 1, name: 'Focus', manufacturer: 1, manufacturer__name: 'Ford'},
1: {id: 2, name: 'F-150', manufacturer: 1, manufacturer__name: 'Ford'},
2: {id: 3, name: 'Model S', manufacturer: 2, manufacturer__name: 'Tesla'}
 

Спасибо за вашу помощь и хорошего воскресенья!

Ответ №1:

Используйте SerializerMethodField. Это поле доступно только для чтения. Он получает свое значение путем вызова метода в классе сериализатора, к которому он присоединен. Его можно использовать для добавления любых данных в сериализованное представление вашего объекта

Внутри serializers.py добавить:

 from rest_framework.serializers import SerializerMethodField

class CarSerializer(ModelSerializer):
    manufacturer__name = SerializerMethodField(help_text="Name of the Car Manufacturer")

    class Meta:
        model = Car
        fields = [
            'id',
            'name',
            'manufacturer',
            'manufacturer__name',
        ]

    def get_manufacturer__name(self, instance: Car):
        return instance.manufacturer.name
 

Комментарии:

1. Ok…so небольшое обновление: мое собственное решение работает только при загрузке данных! При попытке создать данные с тем же сериализатором происходит сбой (я должен создать еще один без дополнительного поля). Ваше решение отлично работает в обеих ситуациях! Итак, еще раз спасибо.

Ответ №2:

ОК,

итак, я нашел решение! Внутри моего serializers.py Я сменил тот, что был для машины, на этот:

 class CarSerializer(ModelSerializer):
    manufacturer_name = CharField(source='manufacturer.name')

    class Meta:
        model = Car
        exclude = [
            'date_created',
        ]
 

Комментарии:

1. Работает ли это так, как вы ожидаете?

2. Да, это работает так, как ожидалось! Но в любом случае спасибо за ваше решение!