Django Rest框架在结果中随机返回空列表,但计数仍然正确
当我尝试使用自定义过滤器时,它在本地开发中一直工作,但当我们部署到生产环境(Docker Swarm)时,我们发现一个问题,即有时API响应随机返回空结果,但计数是正确的。下面是API的示例结果 API响应Django Rest框架在结果中随机返回空列表,但计数仍然正确,django,django-rest-framework,django-filter,django-rest-framework-filters,Django,Django Rest Framework,Django Filter,Django Rest Framework Filters,当我尝试使用自定义过滤器时,它在本地开发中一直工作,但当我们部署到生产环境(Docker Swarm)时,我们发现一个问题,即有时API响应随机返回空结果,但计数是正确的。下面是API的示例结果 API响应 { 'count': 1, 'next': 'http://localhost:8000/api/somethings/?email=test%40example.com&limit=0&offset=0', 'previous': None,
{
'count': 1,
'next': 'http://localhost:8000/api/somethings/?email=test%40example.com&limit=0&offset=0',
'previous': None,
'results': []
}
现在我们需要重新启动一个uwsgi服务(通过重新启动docker swarm来实现此服务),问题暂时得到了解决,并且再次随机发生
这是我们的DRF视图
class SomeView(ListCreateAPIView):
queryset = SomeModel.objects.all()
serializer_class = SomeModelSerializer
filter_backends = (OrderingFilter, DjangoFilterBackend)
filter_class = CustomFilter
ordering = ('id',)
def list(self, request, *args, **kwargs):
if request.GET.get('all', None):
# Do something
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
else:
return super(SomeView, self).list(self, request, *args, **kwargs)
这是我们的定制过滤器
from django_filters.rest_framework.filters import CharFilter
import rest_framework_filters as filters
class CustomFilter(filters.FilterSet):
json_field_separator = '___'
json_field_is = CharFilter(name='json_field', method='filter_json_field')
json_field_is_not = CharFilter(name='json_field', method='exclude_json_field')
def split_lookup_field(self, value):
return dict(field.split(':') for field in value.split(self.json_field_separator))
def filter_json_field(self, queryset, name, value):
try:
lookup_field = self.split_lookup_field(value)
return queryset.filter(**lookup_field)
except (ValueError, FieldError):
return queryset.none()
def exclude_json_field(self, queryset, name, value):
try:
lookup_field = self.split_lookup_field(value)
except (ValueError, FieldError):
return queryset.none()
for query_arg, query_value in lookup_field.items():
queryset = queryset.exclude(**{query_arg: query_value})
return queryset
class Meta:
model = SomeModel
exclude = ['image', 'json_field']
这是我们用于此项目的包的一个版本
Django==1.10.8
djangorestframework==3.6.4
django-filter==1.0.4
djangorestframework-filters==0.10.2
在GenericAPIView中,您可以找到一个名为get_queryset()的方法,该方法如下所示:
def get_queryset(self):
"""
Get the list of items for this view.
This must be an iterable, and may be a queryset.
Defaults to using `self.queryset`.
This method should always be used rather than accessing `self.queryset`
directly, as `self.queryset` gets evaluated only once, and those results
are cached for all subsequent requests.
You may want to override this if you need to provide different
querysets depending on the incoming request.
(Eg. return a list of items that is specific to the user)
"""
assert self.queryset is not None, (
"'%s' should either include a `queryset` attribute, "
"or override the `get_queryset()` method."
% self.__class__.__name__
)
queryset = self.queryset
if isinstance(queryset, QuerySet):
# Ensure queryset is re-evaluated on each request.
queryset = queryset.all()
return queryset
这是一个快速的调用,但我认为您的查询集不会在每个请求上重新评估。
查看此注释:#确保在每个请求中重新评估queryset。将queryset.none()
更改为queryset
中的exclude\u json\u field()
和filter\u json\u field()