Django DRF ListField 反序列化 GET 查询参数中的 id 列表
Django DRF ListField to deserialize list of ids in GET's queryparams
尝试使用 DRF 的 ListField 选项反序列化查询参数中的值列表(下例中的应用程序)。我无法让它工作。无法在网络上找到示例。希望有人能提供一些帮助。
api: /getAppStats/?applications=one,two,three
class MySerializer(serializers.Serializer):
applications = serializers.ListField(child=serializers.CharField())
start_date = serializers.DateField(default=(datetime.datetime.utcnow() - datetime.timedelta(days=30)).date().isoformat())
end_date = serializers.DateField(default=datetime.datetime.utcnow().date().isoformat())
class SomeView(generics.GenericAPIView):
"""
"""
permission_classes = [AllowAny]
serializer_class = MySerializer
def get(self, request, *args, **kwargs):
"""
Just return query params..
"""
serializer = MySerializer(data=request.query_params)
if not serializer.is_valid():
return Response({'stats':'invalid input data'})
return Response({'stats':serializer.data})
我只看到了这个-
{
"stats": {
"applications": [],
"start_date": "2015-05-27",
"end_date": "2015-06-26"
}
}
我发送输入参数的方式不正确吗?我错过了一些微不足道的事情吗?
谢谢!
为同一个键发送多个参数的标准方法是两次使用相同的键名。
你可以这样做:
/getAppStats/?applications=one&applications=two&applications=three
此外,您的服务器将以数组的形式接收应用程序,即 applications[]
而不是 applications
。
class SomeView(generics.GenericAPIView):
"""
"""
permission_classes = [AllowAny]
serializer_class = MySerializer
def get(self, request, *args, **kwargs):
"""
Just return query params..
"""
# get the applications list
applications = request.query_params.getlist('applications[]')
# create a dictionary and pass it to serializer
my_data = {'applications': applications, ...}
serializer = MySerializer(data=my_data)
if not serializer.is_valid():
return Response({'stats':'invalid input data'})
return Response({'stats':serializer.data})
这已经得到解答,但我也在寻找一种解决方案 不 涉及通过使用 getlist 从请求中获取值来改革序列化程序数据(否则有什么意义).
如果您使用 ListField(如果您使用 many=True 也可能),那里有代码可以处理列表,问题是它看起来像你在客户端上使用 jQuery 似乎会导致 "ids[]" 语法破坏序列化程序。
是我会使用的解决方案。
But I wanted to avoid code to pull these values from query params manually and pass it again to serializer. I was expecting the serializer do that for me. – Satish
我也想让序列化器帮我做这个,但是我没有找到。此外,我将此 query_params 列表用于 django-filter
:MultipleChoiceFilter
和 ModelMultipleChoiceFilter
,因此 DRF ListField 对我不起作用。
在我的项目中,Android 请求没有 []
,但只有 IOS 请求有 []
。
我的解决办法是在request.query_params
和request.data
.
中添加装饰器添加数据
def update_get_list_params(func):
def wraps(self, request, *args, **kwargs):
request.query_params._mutable = True
request.data._mutable = True
for key in list(request.query_params.keys()):
# Make sure you know this will not influence the other query_params
if key.endswith('[]'):
new_key = key.split('[]')[0]
value = request.query_params.getlist(key)
if value:
request.query_params.setlist(new_key, value)
for key in list(request.data.keys()):
if key.endswith('[]'):
new_key = key.split('[]')[0]
value = request.data.getlist(key)
if value:
request.data.setlist(new_key, value)
return func(self, request, *args, **kwargs)
return wraps
@update_get_list_params
def get(self, request, *args, **kwargs):
pass
尝试使用 DRF 的 ListField 选项反序列化查询参数中的值列表(下例中的应用程序)。我无法让它工作。无法在网络上找到示例。希望有人能提供一些帮助。
api: /getAppStats/?applications=one,two,three
class MySerializer(serializers.Serializer):
applications = serializers.ListField(child=serializers.CharField())
start_date = serializers.DateField(default=(datetime.datetime.utcnow() - datetime.timedelta(days=30)).date().isoformat())
end_date = serializers.DateField(default=datetime.datetime.utcnow().date().isoformat())
class SomeView(generics.GenericAPIView):
"""
"""
permission_classes = [AllowAny]
serializer_class = MySerializer
def get(self, request, *args, **kwargs):
"""
Just return query params..
"""
serializer = MySerializer(data=request.query_params)
if not serializer.is_valid():
return Response({'stats':'invalid input data'})
return Response({'stats':serializer.data})
我只看到了这个-
{
"stats": {
"applications": [],
"start_date": "2015-05-27",
"end_date": "2015-06-26"
}
}
我发送输入参数的方式不正确吗?我错过了一些微不足道的事情吗?
谢谢!
为同一个键发送多个参数的标准方法是两次使用相同的键名。
你可以这样做:
/getAppStats/?applications=one&applications=two&applications=three
此外,您的服务器将以数组的形式接收应用程序,即 applications[]
而不是 applications
。
class SomeView(generics.GenericAPIView):
"""
"""
permission_classes = [AllowAny]
serializer_class = MySerializer
def get(self, request, *args, **kwargs):
"""
Just return query params..
"""
# get the applications list
applications = request.query_params.getlist('applications[]')
# create a dictionary and pass it to serializer
my_data = {'applications': applications, ...}
serializer = MySerializer(data=my_data)
if not serializer.is_valid():
return Response({'stats':'invalid input data'})
return Response({'stats':serializer.data})
这已经得到解答,但我也在寻找一种解决方案 不 涉及通过使用 getlist 从请求中获取值来改革序列化程序数据(否则有什么意义).
如果您使用 ListField(如果您使用 many=True 也可能),那里有代码可以处理列表,问题是它看起来像你在客户端上使用 jQuery 似乎会导致 "ids[]" 语法破坏序列化程序。
But I wanted to avoid code to pull these values from query params manually and pass it again to serializer. I was expecting the serializer do that for me. – Satish
我也想让序列化器帮我做这个,但是我没有找到。此外,我将此 query_params 列表用于 django-filter
:MultipleChoiceFilter
和 ModelMultipleChoiceFilter
,因此 DRF ListField 对我不起作用。
在我的项目中,Android 请求没有 []
,但只有 IOS 请求有 []
。
我的解决办法是在request.query_params
和request.data
.
def update_get_list_params(func):
def wraps(self, request, *args, **kwargs):
request.query_params._mutable = True
request.data._mutable = True
for key in list(request.query_params.keys()):
# Make sure you know this will not influence the other query_params
if key.endswith('[]'):
new_key = key.split('[]')[0]
value = request.query_params.getlist(key)
if value:
request.query_params.setlist(new_key, value)
for key in list(request.data.keys()):
if key.endswith('[]'):
new_key = key.split('[]')[0]
value = request.data.getlist(key)
if value:
request.data.setlist(new_key, value)
return func(self, request, *args, **kwargs)
return wraps
@update_get_list_params
def get(self, request, *args, **kwargs):
pass