You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django REST Framework序列化器:按状态控制字段显示的自定义验证

当然可以实现!在Django REST Framework(DRF)里,我们可以通过动态控制字段可见性和自定义验证规则,完美实现根据患者就诊状态显示特定字段的需求。下面给你一步步拆解具体方案:

1. 动态控制返回给前端的字段(序列化阶段)

如果你想让不同状态的就诊记录,在前端展示不同的字段,可以重写序列化器的to_representation方法。这个方法负责把模型实例转化为前端能接收的JSON数据,我们可以在这里根据status过滤字段:

from rest_framework import serializers
from .models import Visit

class VisitSerializer(serializers.ModelSerializer):
    class Meta:
        model = Visit
        # 先列出所有可能用到的字段,后续再根据状态过滤
        fields = [
            'patient', 'status', 'status_time', 'visit_start_time',
            'discharge_notes', 'discharged', 'admitted', 'visit_duration',
            'session_start_time', 'session_end_time', 'check_in', 'check_out'
        ]

    def to_representation(self, instance):
        # 先获取默认的序列化数据
        data = super().to_representation(instance)
        
        # 根据就诊状态筛选要返回的字段
        if instance.status == 'ARRIVED':
            # ARRIVED状态下只保留指定字段
            allowed_fields = ['patient', 'status', 'status_time', 'visit_start_time']
        elif instance.status == 'COMPLETE':
            # COMPLETE状态下展示出院相关字段
            allowed_fields = ['patient', 'status', 'status_time', 'discharge_notes', 'visit_duration', 'session_end_time']
        elif instance.status == 'CANCELLED':
            # 取消状态下可以只保留基础信息
            allowed_fields = ['patient', 'status', 'status_time']
        else:
            # 其他状态默认返回所有字段,或者自定义规则
            allowed_fields = list(data.keys())
        
        # 移除不在允许列表中的字段
        for field in list(data.keys()):
            if field not in allowed_fields:
                del data[field]
        
        return data

这个方法的优势是简单直接,完全控制前端能看到的内容,适合展示类场景。

2. 添加自定义字段验证(反序列化阶段)

如果还要确保前端提交的数据符合状态规则(比如ARRIVED状态下不能提交出院记录),可以重写序列化器的validate方法,在数据存入数据库前做校验:

def validate(self, data):
    # 获取当前就诊状态(兼容创建和更新场景)
    status = data.get('status')
    if not status and self.instance:
        status = self.instance.status

    if status == 'ARRIVED':
        # 禁止提交出院相关字段
        forbidden_fields = ['discharge_notes', 'discharged', 'session_end_time']
        for field in forbidden_fields:
            if field in data:
                raise serializers.ValidationError(f"状态为ARRIVED时,不能提交字段 {field}")
        # 确保必填字段存在
        if 'visit_start_time' not in data:
            raise serializers.ValidationError("状态为ARRIVED时,必须填写visit_start_time字段")
    
    elif status == 'COMPLETE':
        # 完成状态下必须提交出院记录
        if 'discharge_notes' not in data or not data['discharge_notes'].strip():
            raise serializers.ValidationError("状态为COMPLETE时,必须填写discharge_notes字段")

    return data

这样就能避免前端提交不符合状态的非法数据,保证数据库数据的一致性。

3. 视图层动态调整序列化器字段(更灵活的场景)

如果需要在视图层面根据请求或实例状态,动态调整序列化器的可用字段(不管是输入还是输出),可以在ViewSet里重写get_serializer方法:

from rest_framework import viewsets

class VisitViewSet(viewsets.ModelViewSet):
    queryset = Visit.objects.all()
    serializer_class = VisitSerializer

    def get_serializer(self, *args, **kwargs):
        serializer = super().get_serializer(*args, **kwargs)
        instance = kwargs.get('instance')
        
        if instance:
            # 根据实例状态动态修改序列化器的字段
            if instance.status == 'ARRIVED':
                serializer.fields = {
                    'patient': serializer.fields['patient'],
                    'status': serializer.fields['status'],
                    'status_time': serializer.fields['status_time'],
                    'visit_start_time': serializer.fields['visit_start_time']
                }
            elif instance.status == 'COMPLETE':
                serializer.fields = {
                    'patient': serializer.fields['patient'],
                    'status': serializer.fields['status'],
                    'status_time': serializer.fields['status_time'],
                    'discharge_notes': serializer.fields['discharge_notes'],
                    'visit_duration': serializer.fields['visit_duration']
                }
        
        return serializer

这种方式适合需要对输入输出字段做统一控制的场景,比如某个状态下前端既不能看到也不能提交某些字段。


内容的提问来源于stack exchange,提问作者Philip Mutua

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:45:06