Django DRF如何拦截已存在同医生预约数据的POST提交请求
解决方案
现有代码问题梳理
- 模型缩进错误:
Appointment类现在缩进在Patient类内部,属于嵌套类,无法正常关联使用,需要先把它移到和Doctor、Patient同级的位置 - 视图逻辑错误:
AppointmentDetailAPI的post方法中,patient_name = Patient.objects.all()和doctor_name = Doctor.objects.all()获取了全量患者和医生数据,没有读取请求提交的目标医生、预约时间参数,无法做冲突校验 - 视图类选型错误:
AppointmentCreateAPI继承的是RetrieveUpdateDestroyAPIView,仅支持查询、更新、删除操作,不支持创建预约的POST请求 - 缺少冲突校验逻辑:没有判断目标医生在指定时间是否已有生效预约
修复步骤
1. 修正模型缩进
把Appointment类移动到Patient类外部,和Doctor、Patient平级,这一步是后续逻辑正常运行的基础。
2. 序列化器增加预约冲突校验(推荐在序列化层做校验,复用性更高)
修改serializers.py中的AppointmentSerializer:
class AppointmentSerializer(serializers.ModelSerializer): """ Appointment serializer class """ class Meta: model = Appointment fields = "__all__" def validate(self, attrs): # 校验目标医生在指定时间是否已有生效预约 is_exist = Appointment.objects.filter( doctor_name=attrs['doctor_name'], appointment_date=attrs['appointment_date'], active=True ).exists() if is_exist: raise serializers.ValidationError("该医生当前时间已有排期,无法预约") return attrs
如果你是按时间段预约(比如单条预约占30分钟),可以把时间判断逻辑改成时间区间重叠判断,示例:
from datetime import timedelta # 假设单条预约时长30分钟 appoint_start = attrs['appointment_date'] appoint_end = appoint_start + timedelta(minutes=30) is_exist = Appointment.objects.filter( doctor_name=attrs['doctor_name'], active=True, appointment_date__lt=appoint_end, appointment_date__gte=appoint_start ).exists()
3. 修正视图逻辑
你可以直接把创建功能整合到AppointmentDetailAPI的post方法中,修改views.py的对应代码:
class AppointmentDetailAPI(APIView): def get(self, request): appointment = Appointment.objects.all() serializer = AppointmentSerializer(appointment, many=True) return Response(serializer.data) def post(self, request): serializer = AppointmentSerializer(data=request.data) # 序列化器会自动执行我们上面加的冲突校验 serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED)
如果需要单独的创建接口,也可以把AppointmentCreateAPI改成支持创建的视图类:
class AppointmentCreateAPI(generics.CreateAPIView): queryset = Appointment.objects.all() serializer_class = AppointmentSerializer
内容的提问来源于stack exchange,提问作者Dubey Ravi vinod
相关产品推荐
相关产品推荐

