Ошибка атрибута в /api/module/list/

#django #django-rest-framework

#django #django-rest-framework

Вопрос:

Я хочу, чтобы многие поля отображались в сериализаторе модуля вместо идентификатора, это мои сериализаторы

 class TrainerSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = ['id', ]


class ModuleSerializer(serializers.ModelSerializer):

    trainer = serializers.CharField(source='trainer.username')

    class Meta:
        model = Module
        fields = ['id', 'title', 'duration', 'trainer', 

'publish_choice']

class Trainer(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)

    def __str__(self):
        return str(self.user)

    class Meta:
        ordering = ['pk']


class Module(models.Model):
    title = models.CharField(max_length=80, unique=True)
    duration = models.IntegerField(verbose_name='Duration in Days/ Weeks', blank=True, null=True)
    trainer = models.ManyToManyField(Trainer, blank=True)
    detail = models.TextField(verbose_name='Program Details', blank=True, null=True)
    notify = models.BooleanField(default=False)
    publish_choice = models.CharField(verbose_name='Publish/ Draft',
                                      max_length=80, choices=PUBLISH_CHOICES, default='publish')
 

и это сообщение об ошибке

Получил ошибку атрибута при попытке получить значение для поля trainer в сериализаторе ModuleSerializer . Поле сериализатора может быть названо неправильно и не соответствовать какому-либо атрибуту или ключу Module экземпляра. Исходный текст исключения был: объект ‘ManyRelatedManager’ не имеет атрибута ‘username’.

Ответ №1:

У нас есть параметр глубины в метаклассе сериализатора. мы можем использовать его, как показано ниже. depth=1 будет извлекать все поля отношения.

 class ModuleSerializer(serializers.ModelSerializer):

     class Meta:
        model = Module
        fields = ['id', 'title', 'duration', 'trainer', 'publish_choice']
        depth = 1
 

для справки DRF-документация по сериализаторам

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

1. @Biju рассмотрите возможность принятия этого ответа, если он сработал для вас.

2. Тщательно продумайте глубину. Если в вашей модели больше fk или многие ко многим, depth запросит все это.

Ответ №2:

Это вызывает исключение, потому serializers.CharField(source='trainer.username') что не соответствует ManyRelatedManager модели trainer = models.ManyToManyField(Trainer, blank=True) .

Если вы хотите получить все имя пользователя вместо идентификатора, вы можете попробовать добавить пользовательский serialzier тип следующим образом:

 class ModuleSerializer(serializers.ModelSerializer):
     trainer = serializers.SerializerMethodField()

     def get_trainer(self, obj):
        results = []
        for item in obj.trainers.all():
            results.append(item.username)
        return results

     class Meta:
        model = Module
        fields = ['id', 'title', 'duration', 'trainer', 'publish_choice']
 

trainer вернет массив username отношения с Module

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

1. это выдает ошибку «объект ‘Module’ не имеет атрибута ‘users'»

2. ах, старший, я отредактировал свой ответ. можете ли вы попробовать еще раз?