Django REST 框架 : Posting to URL with ID in URL

标签 django django-models django-rest-framework django-views django-serializer

给出以下人为设计的示例,我如何POST 到路径中带有 ID 的 URL 并让它解析模型实例,而不是在 POST 中包含模型实例> body 本身?

网址.py

path("api/schools/<int:pk>/student/", views.CreateStudentView.as_view(), name="createStudent")

模型.py

class School(models.Model):
    name = models.CharField(default="", max_length=128)
    address = models.CharField(default="", max_length=128)
    mascot = models.CharField(default="", max_length=128)


class StudentModel(models.Model):
    first_name = models.CharField(default="", max_length=128)
    last_name = models.CharField(default="", max_length=128)
    notes = models.CharField(default="", max_length=512)
    school = models.ForeignKey(School, on_delete=models.CASCADE)

序列化器.py

class CreateStudentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = ("first_name", "last_name")

View .py

class CreateStudentView(generics.CreateAPIView):
    serializer_class = CreateStudentSerializer
    queryset = Student.objects.all()

我希望能够将新学生的名字和姓氏POST 到 URL,以便在我的数据库中创建新学生。但是,因为我没有在我的 POST 正文中提供 School 对象,所以我得到了一个错误。我希望我的代码能够解析我想将学生添加到哪所学校,因为 URL 包含 ID。

当我POST 下列正文到/api/schools/1/student/ 时出现错误。数据库中确实存在ID为1的学校。

{
    "first_name": "John",
    "last_name": "Smith"
}
IntegrityError at /api/schools/1/student/

NOT NULL constraint failed: students_school.school_id

最佳答案

最简单的方法是覆盖 CreateStudentView 的创建方法。 URL 参数存储在 self.kwargs 中,因此您可以从那里检索它,并将其注入(inject)序列化程序:

class CreateStudentView(generics.CreateAPIView):
    serializer_class = CreateStudentSerializer
    queryset = Student.objects.all()

    def get_serializer(self, *args, **kwargs):
        serializer_class = self.get_serializer_class()
        kwargs["context"] = self.get_serializer_context()
        
        # Check if a pk was passed through the url.
        if 'pk' in self.kwargs:        
            modified_data = self.request.data.copy()
            modified_data['school'] = self.kwargs.get('pk')
            kwargs["data"] = modified_data
            return serializer_class(*args, **kwargs)

        # If not mind, move on.
        return serializer_class(*args, **kwargs)

归功于 this article ,您可以在其中详细了解其工作原理。

关于Django REST 框架 : Posting to URL with ID in URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64154970/

相关文章:

django - 如何自动让syncdb添加列(不需要完全迁移)

python - 具有自定义多对多映射的 Django 序列化模型

用于下拉列表的 Django 小部件

Django:如何更改没有中间表的多对多内联文本?

python - 在python中设置默认的日期时间格式

python - 'NoneType' 对象在泡沫中没有属性 'str'

django - 在模板中扩展ManyToManyField

python - 在 Django ModelForm 字段中包含自动生成的主键

python - Django REST 框架 : 'WSGIRequest' object has no attribute 'query_params'

python - 在 DRF 中管理自定义序列化器的最佳方法是什么