Django REST Framework基于外键过滤CreateModelMixin可选字段
Django REST Framework 动态过滤关联字段选项解决方案
实现逻辑
该需求需要在序列化器层动态调整关联算法的可选查询集,同时兼顾创建、更新两种场景的参数获取,可自动完成提交校验,无需额外编写视图层过滤逻辑。
代码修改
1. 调整ABTest序列化器
将原有ABTestSerializer替换为以下实现:
class ABTestSerializer(serializers.ModelSerializer): # 显式定义两个算法外键字段,初始查询集设为空,后续动态赋值 parent_mlalgorithm_1 = serializers.PrimaryKeyRelatedField(queryset=MLAlgorithm.objects.none()) parent_mlalgorithm_2 = serializers.PrimaryKeyRelatedField(queryset=MLAlgorithm.objects.none()) class Meta: model = ABTest read_only_fields = ("id", "created_at") fields = ( "id", "title", "created_by", "created_at", "parent_endpoint", "parent_mlalgorithm_1", "parent_mlalgorithm_2") def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) endpoint_id = None # 更新场景:取已有ABTest实例绑定的endpoint_id if self.instance: endpoint_id = self.instance.parent_endpoint_id # 新建场景:从请求数据中取提交的parent_endpoint值 elif 'request' in self.context and self.context['request'].method == 'POST': endpoint_id = self.context['request'].data.get('parent_endpoint') # 拿到endpoint_id后过滤对应归属的算法,更新字段查询集 if endpoint_id: algo_queryset = MLAlgorithm.objects.filter(parent_endpoint_id=endpoint_id) self.fields['parent_mlalgorithm_1'].queryset = algo_queryset self.fields['parent_mlalgorithm_2'].queryset = algo_queryset
2. 可选:新增联动查询接口(前后端分离场景)
如果需要实现前端下拉选项实时跟随选中Endpoint更新,可新增专属查询接口:
# views.py 新增接口 from rest_framework.response import Response from rest_framework.decorators import api_view @api_view(['GET']) def get_algorithms_by_endpoint(request, endpoint_id): algos = MLAlgorithm.objects.filter(parent_endpoint_id=endpoint_id) serializer = MLAlgorithmSerializer(algos, many=True) return Response(serializer.data) # urls.py 新增路由 urlpatterns = [ # 其他原有路由 path('endpoint/<int:endpoint_id>/algorithms/', get_algorithms_by_endpoint, name='endpoint-algorithms'), ]
前端监听parent_endpoint下拉框的变更事件,携带选中的Endpoint ID调用上述接口,拿到返回值后更新两个算法下拉的选项即可。
效果说明
- 提交创建/更新请求时,序列化器会自动校验选中的两个算法是否属于指定Endpoint,非法ID会直接返回校验错误,保证数据合法性
- DRF自带的可浏览API页面在提交数据时,填写
parent_endpoint值后刷新页面,下拉列表会自动过滤出对应归属的算法选项
内容的提问来源于stack exchange,提问作者ILIAS TOUGUI
相关产品推荐
相关产品推荐

