如何在Django Rest函数视图中使用序列化器验证?如何通过GET请求更新实例?
在Django REST框架的函数视图中使用序列化器验证 + 用GET请求更新实例
嘿,针对你的两个需求,我来一步步给你拆解解决方案:
一、在基于函数的视图中使用序列化器验证
首先,咱们需要先定义一个序列化器来处理验证逻辑——哪怕你只是要验证student_id和class_id的合法性,序列化器也能帮你把验证逻辑抽离出来,让视图更干净,还能统一处理错误提示。
1. 定义序列化器
在你的app里新建(或修改)serializers.py:
from rest_framework import serializers from .models import Class, Student class AddStudentSerializer(serializers.Serializer): pk = serializers.IntegerField() student_id = serializers.IntegerField() # 单独验证班级ID合法性 def validate_pk(self, value): if not Class.objects.filter(id=value).exists(): raise serializers.ValidationError("指定的班级不存在") return value # 单独验证学生ID合法性 def validate_student_id(self, value): if not Student.objects.filter(id=value).exists(): raise serializers.ValidationError("指定的学生不存在") return value # 联合验证:检查学生是否已在班级中 def validate(self, data): class_obj = Class.objects.get(id=data['pk']) student_obj = Student.objects.get(id=data['student_id']) if student_obj in class_obj.students.all(): raise serializers.ValidationError("该学生已经在这个班级里了") return data
2. 在函数视图中集成序列化器验证
修改你的views.py,把序列化器的验证逻辑加进去,同时用DRF的@api_view装饰器让视图更好地支持DRF特性:
from rest_framework.decorators import api_view from rest_framework.response import Response from .models import Class, Student from .serializers import AddStudentSerializer from django.shortcuts import get_object_or_404, redirect @api_view(['GET']) # 明确允许GET请求 def add_student(request, pk, student_id): # 构造序列化器需要的验证数据 data = { 'pk': pk, 'student_id': student_id } # 初始化序列化器并传入数据 serializer = AddStudentSerializer(data=data) # 执行验证,失败时自动抛出异常并返回标准错误响应 if serializer.is_valid(raise_exception=True): # 验证通过后执行添加操作 class_ = get_object_or_404(Class, id=pk) student = get_object_or_404(Student, id=student_id) class_.students.add(student) # 你可以选择返回API响应,或者保留原来的页面跳转 # return Response({"message": "学生添加成功"}, status=200) return redirect('class-detail', pk=pk)
二、通过GET请求更新实例的注意事项
你当前的代码已经是用GET请求执行更新操作了,但这里要提一句:按照RESTful规范,更新/创建资源应该用POST/PUT/PATCH请求,GET请求的语义是获取资源,不应该修改服务器状态。不过如果你因为特定场景必须用GET,上面的代码已经可以满足需求——我们在GET请求中完成了资源的更新(添加学生到班级)。
如果希望通过GET查询参数传递数据(而不是URL路径参数),可以调整视图和路由:
修改后的视图
@api_view(['GET']) def add_student(request): # 从查询参数中获取数据,比如请求路径为 /classes/add_student/?pk=1&student_id=2 pk = request.query_params.get('pk') student_id = request.query_params.get('student_id') data = {'pk': pk, 'student_id': student_id} serializer = AddStudentSerializer(data=data) if serializer.is_valid(raise_exception=True): class_ = get_object_or_404(Class, id=pk) student = get_object_or_404(Student, id=student_id) class_.students.add(student) return redirect('class-detail', pk=pk)
修改后的路由(urls.py)
urlpatterns=[ url(r'^classes/add_student/', views.add_student), ]
总结
- 序列化器验证的核心流程:构造验证数据→初始化序列化器→调用
is_valid()→处理验证通过后的业务逻辑 - 用GET请求更新实例可以实现,但要注意REST规范的语义问题,非必要场景更推荐用POST/PUT
@api_view装饰器能让函数视图更好地和DRF集成,自动处理异常和标准响应格式
内容的提问来源于stack exchange,提问作者Bill Vergara
相关产品推荐
相关产品推荐

