【问题标题】:Django DRF (De-)Serializer not working for me?Django DRF (De-)Serializer 对我不起作用?
【发布时间】:2020-12-19 01:52:30
【问题描述】:

我偶然发现了一个我不明白的案例。

我有两个相关的模型:

class Course(models.Model):
  code = models.CharField(max_length=10, default='')
  semester = models.CharField(max_length=10, default='')

  class Meta:
        unique_together = [['code', 'semester']]

和:

class StudentWork(models.Model):
  code = models.CharField(max_length=10, default='')
  course = models.ForeignKey(Course,on_delete=models.CASCADE, related_name='student_works')
  deadline = models.DateTimeField(blank=True)

在 StudentWorkSerializer 中,我想将 course 字段扩展为 [代码,学期]:

class CourseNaturalSerializer(serializers.ModelSerializer):
    class Meta:
        model = Course
        fields = ['code', 'semester']

class StudentWorkWithCourseSerializer(serializers.ModelSerializer):
    course = CourseNaturalSerializer(read_only=True)
    
    class Meta:
       model = StudentWork
       fields = ['code', 'course', 'deadline']

这非常适用于 GET,例如我收到这个:

{'code': 'HW1', 'course': {'code': 'T101', 'semester': 'S20'}, 'deadline': '2020-09-04T23:59:00+03:00'}

但这不适用于 POST:

POST /studentworks json=dict(code='HW2', course={"code": "T101", "semester": "S20"}, deadline="2020-09-04T23:59")

在堆栈跟踪中说:

django.db.utils.IntegrityError: NOT NULL constraint failed: botdb_studentwork.course_id

所以在我看来 {"code": "T101", "semester": "S20"} 没有反序列化为 Course 对象,并且它的 id 没有传递给 StudentWork 的 create?

我该怎么办?

提前致谢!

更新: 有人问我相关字段序列化程序上的 read_only=True 是否是故意的?

如果我不设置它,我会得到:

'{"course":{"non_field_errors":["The fields code, semester must make a unique set."]}}'

这让我想到它想在我想创建一个 StudentWork 时为我创建一个新课程(因为代码和学期被声明为 unique_together)。我不想要。

如果我在 POST 数据中将学期改为 S21,我会得到:

AssertionError: The `.create()` method does not support writable nested fields by default.
Write an explicit `.create()` method for serializer `botdb.serializers.StudentWorkWithCourseSerializer`, or set `read_only=True` on nested serializer fields.

因此我感到困惑 - 我不知道如何阻止它尝试创建新课程,而只是使用相关领域中的现有课程。

【问题讨论】:

标签: python django django-rest-framework django-serializer


【解决方案1】:

您可以考虑在 POST 中仅传递 course_id。

【讨论】:

  • 是的,这当然可以,但我确实想通过代码和学期组合而不是课程 ID。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-12
  • 2011-11-26
相关资源
最近更新 更多