Django Rest框架:如何动态返回字段子集
我想按字段名筛选并返回子集,而不是返回所有字段名。例如,这里我按id和名称进行过滤。它应该只返回json格式的这个二维。 我在网站上找到了很多解决方案,我做的和建议的完全一样,但我没有得到预期的结果。你能帮帮我吗 my URL.py:Django Rest框架:如何动态返回字段子集,django,django-rest-framework,django-serializer,django-filter,drf-queryset,Django,Django Rest Framework,Django Serializer,Django Filter,Drf Queryset,我想按字段名筛选并返回子集,而不是返回所有字段名。例如,这里我按id和名称进行过滤。它应该只返回json格式的这个二维。 我在网站上找到了很多解决方案,我做的和建议的完全一样,但我没有得到预期的结果。你能帮帮我吗 my URL.py: router = routers.DefaultRouter() urlpatterns = [ path('', include(router.urls)), path('edges/', edge_list), path('edges
router = routers.DefaultRouter()
urlpatterns = [
path('', include(router.urls)),
path('edges/', edge_list),
path('edges/<int:pk>/', edge_detail),
path('network/<int:pk>/edges/', edges_of_a_network),
]
这里有一个复制过去的例子
我要筛选字段的序列化程序类
class EdgeSerializer(DynamicFieldsModelSerializer, serializers.ModelSerializer):
source = serializers.SerializerMethodField(method_name='get_node_source')
target = serializers.SerializerMethodField(method_name='get_node_target')
road_type = serializers.SerializerMethodField(
method_name='get_road_type_id')
class Meta:
model = Edge
fields = (
'id', 'edge_id', 'name', 'length', 'speed',
'lanes', 'param1', 'param2', 'param3', 'network',
'road_type', 'source', 'target'
)
def get_road_type_id(self, instance):
return {"id": instance.road_type.road_type_id,
"name": instance.road_type.name}
def get_node_source(self, instance):
return {"node_id":instance.source.node_id, "node_name": instance.source.name}
def get_node_target(self, instance):
return {"node_id":instance.target.node_id, "node_name": instance.target.name}
您如何使用视图中的序列化程序?您可以初始化为:
fields=request.query\u params.get('fields')
fields_cleaned=[field.replace('-','')表示字段中的字段]
ser=EdgeSerializer(fields=fields\u cleaned,instance=queryset,many=True)
打印(序列数据)
我刚刚添加了视图。我保持相同的视图,如果没有过滤器,它将返回所有字段。我错了吗?@aba2s您的代码显示了所有字段,看起来还不错。如果fields\u
不是空的,您可以简单地编写if
语句并传递fields
参数。例如:`if cleanned:SerializerClass(fields,qs)else:SerializerClass(qs)@raviashikiri,我遵循了你的建议,但没有得到预期的结果。我错过了一些我不明白的东西。我在下面添加了视图
class DynamicFieldsModelSerializer(serializers.ModelSerializer):
"""
A ModelSerializer that takes an additional `fields` argument that
controls which fields should be displayed.
"""
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
fields = kwargs.pop('fields', None)
# Instantiate the superclass normally
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
if fields is not None:
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
existing = set(self.fields)
for field_name in existing - allowed:
self.fields.pop(field_name)
class EdgeSerializer(DynamicFieldsModelSerializer, serializers.ModelSerializer):
source = serializers.SerializerMethodField(method_name='get_node_source')
target = serializers.SerializerMethodField(method_name='get_node_target')
road_type = serializers.SerializerMethodField(
method_name='get_road_type_id')
class Meta:
model = Edge
fields = (
'id', 'edge_id', 'name', 'length', 'speed',
'lanes', 'param1', 'param2', 'param3', 'network',
'road_type', 'source', 'target'
)
def get_road_type_id(self, instance):
return {"id": instance.road_type.road_type_id,
"name": instance.road_type.name}
def get_node_source(self, instance):
return {"node_id":instance.source.node_id, "node_name": instance.source.name}
def get_node_target(self, instance):
return {"node_id":instance.target.node_id, "node_name": instance.target.name}
@api_view(['GET', 'POST'])
def edge_list(request):
"""
List all edges of all networks, or create a new edge.
"""
if request.method == 'GET':
edges = Edge.objects.all()
fields = request.query_params.get('fields')
fields_cleaned = [field.replace('-', '') for field in fields]
if not fields_cleaned:
serializer = EdgeSerializer(fields=fields, instance=edges, many=True)
else:
serializer = EdgeSerializer(instance=edges, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = EdgeSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.error, status=status.HTTP_400_BAD_REQUEST)