简体   繁体   中英

How to create custom list field in serializer, which contains another serializer(model), django rest framework?

I need to use a list of one model serializer in another, I have tried use SerializerMethodField() but didn't succeed.
So i have following codes:

models.py

class TyresGroup(models.Model):
    code  = models.CharField("Наименование группы колес", max_length=50)
    brand = models.CharField("Бренд", max_length=50)

    class Meta:
        verbose_name        = "Группа колёс"
        verbose_name_plural = "Группы колёс"

def get_image_filename(instance, filename):
    code = instance.tyres_group.code
    slug = slugify(code)
    return "post_images/%s-%s" % (slug, filename)


class Images(models.Model):
    tyres_group = models.ForeignKey(TyresGroup, default=None, on_delete=models.CASCADE)
    image       = models.ImageField(upload_to=get_image_filename, verbose_name='Image')

    class Meta:
        verbose_name        = "Фотография"
        verbose_name_plural = "Фотографии"


class Tyre(models.Model):
    group        = models.ForeignKey(TyresGroup, blank=True, on_delete=models.CASCADE)
    images       = models.ManyToManyField(Images, related_name='tyresgroup', blank=True)
    type         = models.CharField("Тип колеса", max_length=2, choices=TYRE_TYPES)
    code         = models.CharField("Код протектора", max_length=10)
    title        = models.CharField("Название", max_length=30)
    width        = models.CharField('Ширина', max_length=5, choices=WIDTH)
    height       = models.CharField('Высота', max_length=5, choices=HEIGHT)
    radius       = models.CharField('Радиус', max_length=5, choices=RADIUS)
    speed_index  = models.IntegerField('Индекс скорости')
    tread_depth  = models.IntegerField('Глубина протектора')
    standard     = models.FloatField('Какой-то стандарт')
    oa_dia       = models.IntegerField("OA DIA")
    max_pressure = models.IntegerField('Максимальное давление(КРА/PSI)')
    certificate  = models.CharField('Сертификат качества', max_length=5)
    distance     = models.IntegerField("Преодолимая дистанция колёс")
    max_loading  = models.IntegerField("Максимальная нагрузка")

    class Meta:
        verbose_name        = "Колесо"
        verbose_name_plural = "Колёса"

and serializers.py:

class TyreSerializer(serializers.ModelSerializer):
    images = ImagesSerializer(many=True)
    class Meta:
        model = Tyre
        fields = '__all__'


class TyresGroupSerializer(serializers.ModelSerializer):
    # tyres = serializers.SerializerMethodField()

    # def get_tyres(self, instance):
    #     queryset = Tyre.objects.all()
    #     return queryset

    class Meta:
        model = TyresGroup
        fields = ['id', 'code', 'brand'] #, 'tyres']

What i want to get:

[
    {
        "id": 1,
        "group": "VH200",
        "brand": "Aventus",
        "tyres": [
            {
                "id": 1,
                "group": 1,
                "images": [...],
                "type": "Л",
                ...etc
            },
            {
                "id": 2,
                "group": 1,
                "images": [...],
                "type": "Л",
                ...etc
            }
        ]
    },
    ...etc
]

What i have now:

[
    {
        "id": 1,
        "group": "VH200",
        "brand": "Aventus"
    },
    {
        "id": 2,
        "group": "VH201",
        "brand": "Columbus"
    }
    ...etc
]

You have to update your TyresGroupSerializer as below...

class TyresGroupSerializer(serializers.ModelSerializer):
    tyres = TyreSerializer(source='get_tyres', many=True)

    def get_tyres(self, instance):
        queryset = Tyre.objects.filter(group=instance)
        return queryset

    class Meta:
        model = TyresGroup
        fields = ['id', 'code', 'brand', 'tyres']

You can use SerializerMethodField() field in TyresGroupSerializer as follow.

class TyresSerializer(serializers.ModelSerializer):
    images = ImagesSerializer(many=True)
    tyregroups = serializers.SerializerMethodField(read_only=True) # If you do not want to write data of Tyre object otherwise you can set it to False

    def get_tyregroups(self, instance):
        serializer_class = TyreGroupSerializer(instance.group, many=True)
        serialized_data = serializer_class.data
        return serialized_data

    class Meta:
        model = Tyres
        fields = ['id', 'group', 'images', 'type', 'tyregroups'] # add all other fields which you want to in json

class TyresGroupSerializer(serializers.ModelSerializer):
    class Meta:
        model = TyresGroup
        fields = '__all__'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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