在Django中创建Answer时,如何验证form_key为有效UUID?
验证form_key的UUID格式并关联Form的实现方案
方法一:利用DRF序列化器的内置验证(推荐)
DRF的serializers.UUIDField本身会自动验证传入值是否为有效UUID格式,同时我们可以在序列化器中添加表单存在性验证,把逻辑统一放在序列化层,更符合DRF的设计规范。
修改后的代码如下:
class AnswerSerializer(serializers.ModelSerializer): form_key = serializers.UUIDField(write_only=True) class Meta: model = imported_models.Answer fields = ['id', "answer", "form_key"] # 必须将form_key加入fields,序列化器才会处理该字段 def validate_form_key(self, value): # 验证form_key对应的Form是否存在 if not imported_models.Form.objects.filter(key=value).exists(): raise serializers.ValidationError("对应的表单不存在") return value def create(self, validated_data): # 从验证后的数据中取出form_key,关联对应的Form并创建Answer form_key = validated_data.pop('form_key') form = imported_models.Form.objects.get(key=form_key) return imported_models.Answer.objects.create(form=form, **validated_data)
然后简化视图层,删除原来的perform_create方法:
class AnswerViewset(viewsets.ModelViewSet): queryset = imported_models.Answer.objects.all() serializer_class = imported_serializers.AnswerSerializer
这样做的优势:
- UUID格式验证无需手动编写,由
UUIDField自动完成,格式错误时会返回标准的序列化错误信息 - 表单存在性验证放在序列化器的
validate方法中,错误信息会和其他字段错误统一返回,前端处理更一致 - 创建逻辑移到序列化器的
create方法,视图层只负责请求分发,职责更清晰
方法二:在视图层手动验证格式(不推荐)
如果一定要在视图层处理格式验证,可以用Python内置的uuid模块解析form_key,判断是否为有效UUID:
import uuid from rest_framework import status from rest_framework.response import Response class AnswerViewset(viewsets.ModelViewSet): queryset = imported_models.Answer.objects.all() serializer_class = imported_serializers.AnswerSerializer def perform_create(self, serializer): form_key = self.request.data.get('form_key') # 验证UUID格式 try: uuid.UUID(form_key) except ValueError: return Response(status=status.HTTP_400_BAD_REQUEST, data={"detail": "form_key不是有效的UUID格式"}) # 验证表单是否存在 form = imported_models.Form.objects.filter(key=form_key).first() if not form: return Response(status=status.HTTP_400_BAD_REQUEST, data={"detail": "表单不存在"}) serializer.save(form=form)
注意:这种方式违反了DRF的分层设计原则,数据验证逻辑应该由序列化器负责,视图层尽量只处理请求响应流程。
内容的提问来源于stack exchange,提问作者SaimumIslam27
相关产品推荐
相关产品推荐

