Django DRF能否用单个视图与序列化器实现不同字段返回需求
你完全不需要新增重复的视图类,仅通过修改现有代码就能实现两种返回场景,有两种常用实现方案可选:
小提示:你现有代码里
User.object.all()存在笔误,应该是User.objects.all(),记得修改避免运行报错。
方案1:同一路由根据请求参数动态返回字段
这种方案适合同一个接口地址,在不同业务场景下切换返回字段的需求,只需要修改序列化器和视图的少量代码即可:
第一步:改造现有序列化器支持动态字段过滤
class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['id', 'first_name', 'last_name', 'city'] def __init__(self, *args, **kwargs): # 取出是否仅返回城市的标记 only_city = kwargs.pop('only_city', False) super().__init__(*args, **kwargs) # 仅保留city字段 if only_city: allowed_fields = {'city'} for field in list(self.fields.keys()): if field not in allowed_fields: self.fields.pop(field)
第二步:修改视图类的序列化器获取逻辑
class UserDetail(generics.RetrieveDestroyAPIView): permission_classes = [IsAuthenticatedOrReadOnly] # 修正笔误 queryset = User.objects.all() serializer_class = UserSerializer def get_object(self, queryset=None, **kwargs): item = self.kwargs.get('pk') return generics.get_object_or_404(User, id=item) def get_serializer(self, *args, **kwargs): # 检测请求是否携带only_city参数 if self.request.query_params.get('only_city') == '1': kwargs['only_city'] = True return super().get_serializer(*args, **kwargs)
调用方式
- 返回全部字段:请求
GET /<uuid:pk> - 仅返回city字段:请求
GET /<uuid:pk>?only_city=1
方案2:不同路由分开返回对应字段
如果希望用两个不同的接口地址分别返回全量字段和仅城市字段,不需要新增重复的视图类,直接在路由配置里给视图传入不同的序列化器即可:
第一步:保留你写的仅返回城市的序列化器
class UserJustCitySerializer(serializers.ModelSerializer): class Meta: model = User fields = ['city']
第二步:修改路由配置
# 原路由返回全部用户字段 path('<uuid:pk>', UserDetail.as_view(), name='user_detail'), # 新路由仅返回城市字段,直接传入指定序列化器即可 path('<uuid:pk>/city', UserDetail.as_view(serializer_class=UserJustCitySerializer), name='user_city')
调用方式
- 返回全部字段:请求
GET /<uuid:pk> - 仅返回city字段:请求
GET /<uuid:pk>/city
内容的提问来源于stack exchange,提问作者some nooby questions
相关产品推荐
相关产品推荐

