【问题标题】:AttributeError at /api/module/list//api/module/list/ 处的 AttributeError
【发布时间】:2020-12-07 04:05:23
【问题描述】:

我希望在模块序列化程序中显示多对多字段而不是 id,这些是我的序列化程序

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')

这是错误信息

尝试在序列化程序 ModuleSerializer 上获取字段 trainer 的值时出现 AttributeError。 序列化程序字段可能命名不正确,并且与 Module 实例上的任何属性或键都不匹配。 原始异常文本是:“ManyRelatedManager”对象没有属性“用户名”。

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    我们在序列化器 MetaClass 中有一个深度参数。我们可以像下面这样使用它。 depth=1 将检索关系的所有字段。

    class ModuleSerializer(serializers.ModelSerializer):
    
         class Meta:
            model = Module
            fields = ['id', 'title', 'duration', 'trainer', 'publish_choice']
            depth = 1
    

    供参考DRF-Documentation on serializers

    【讨论】:

    • @Biju 考虑接受这个答案,如果它对你有用。
    • 小心有深度。如果你的模型有更多的 fk 或多对多,depth 将查询所有这些。
    【解决方案2】:

    它引发异常是因为serializers.CharField(source='trainer.username') 与模型trainer = models.ManyToManyField(Trainer, blank=True) 中的ManyRelatedManager 不匹配。

    如果您想获取所有用户名而不是 id,可以尝试添加自定义类型 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 将返回 usernameModule 关系的数组

    【讨论】:

    • 这会抛出错误“'Module' object has no attribute 'users'”
    • 啊先生,我编辑了我的答案。你能再试一次吗?
    猜你喜欢
    • 2012-03-06
    • 2018-02-11
    • 2023-03-11
    • 2015-07-11
    • 2022-06-20
    • 2022-12-01
    • 2014-07-13
    • 1970-01-01
    • 2023-01-12
    相关资源
    最近更新 更多