【问题标题】:Getting AttribueError by SlugRelatedField despite the object being saved尽管对象被保存,但通过 SlugRelatedField 获取 AttribueError
【发布时间】:2021-08-14 11:44:57
【问题描述】:

我正在创建一个 API 来拯救班主任。现在 ClassTeacher 模型中的所有字段都是外部字段,所以我在序列化程序中使用了 SlugRelatedField。看起来 SlugRelatedField 不支持像“user__username”这样的属性查找并引发属性错误但是对象仍在保存中。

models.py

class ClassTeacher(models.Model):
    teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)
    class_name = models.ForeignKey(Classes, on_delete=models.CASCADE)
    school_id = models.ForeignKey(School, on_delete=models.CASCADE)

序列化器.py

class ClassTeacherSerializer(ModelSerializer):
    teacher = SlugRelatedField(slug_field='user__username', queryset=Teacher.objects.all()) <---- this is causing the error
    class_name = SlugRelatedField(slug_field='class_name', queryset=Classes.objects.all())
    school_id = SlugRelatedField(slug_field='school_id__username', queryset=School.objects.all()) <---- and I am assuming that this will too

    class Meta:
        model = ClassTeacher
        fields = '__all__'

我尝试在 Teacher 模型中添加 @property 来检索用户名并使用 slug_field 中的属性,但这也不起作用。

如何保存对象而不出现错误?

编辑 1:

teachers/models.py

class Teacher(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=30)
    photo = models.URLField()

teacher/serializers.py

class TeacherSerializer(ModelSerializer):
    class Meta:
        model = Teacher
        fields = '__all__'

学校/models.py

class School(models.Model):
    school_id = models.OneToOneField(User, on_delete=models.CASCADE)
    principal = models.CharField(max_length=50)
    name = models.CharField(max_length=50)
    photo = models.URLField()

学校/serializers.py

class SchoolSerializer(ModelSerializer):
    class Meta:
        model = School
        fields = '__all__'

编辑 2:

这是我通过引用here 使用@property 的方式:

teacher/models.py

class Teacher(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=30)
    photo = models.URLField()

#Here's the extra property part
    @property
    def username(self):
        return self.user.username

classteacher/serializers.py

class ClassTeacherSerializer(ModelSerializer):
    #Here I changed user__username to just username as mentioned in the above link
    teacher = SlugRelatedField(slug_field='username', queryset=Teacher.objects.all())
    class_name = SlugRelatedField(slug_field='class_name', queryset=Classes.objects.all())
    school_id = SlugRelatedField(slug_field='school_id__username', queryset=School.objects.all())

    class Meta:
        model = ClassTeacher
        fields = '__all__'

【问题讨论】:

  • 请同时提供模型教师实现
  • @Someprogammer 我已经进行了编辑。现在就来看看吧。
  • Hello @AyushGupta DRF 不允许在 SlugRelatedFields 上进行嵌套属性查找
  • @AnkitTiwari 是的,我也想到了,但有什么替代方案?
  • 您可以使用@property 获取关系

标签: python django


【解决方案1】:

尝试将序列化器字段从教师重命名为用户并使用 slug_field='username'

【讨论】:

  • 请您详细说明一下,因为教师模型中的序列化器字段已经命名为用户?我将包括教师和学校的序列化程序。
  • 将字段名称从 ClassTeacherSerializer.teacher 更改为 ClassTeacherSerializer.user,它应该可以工作;如果您想将教师添加为​​直接字段,我会尝试在 get_queryset() 视图方法中对其进行 .annotate() 或编写自定义 ClassTeacherField(参见django-rest-framework.org/api-guide/fields/#custom-fields
  • 问题很可能是它试图在您的模型中找到一个名为“teacher”的关系但它找不到它,因为模型中没有这样的字段,只有“user”。另一种解决方案是在模型中将“用户”更改为“教师”。在我看来,最好的一个
【解决方案2】:

例如,您可以使用@property

class User(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=30)
    photo = models.URLField()
    
    @property
    def get_username(self):
       return Teacher.objects.filter(user_id=self.id)

在你的ClassTeacherSerializer 中使用slug_field='username'

让我知道它是否有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-04
    • 2016-02-17
    • 1970-01-01
    相关资源
    最近更新 更多