Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django Rest框架在结果中随机返回空列表,但计数仍然正确_Django_Django Rest Framework_Django Filter_Django Rest Framework Filters - Fatal编程技术网

Django Rest框架在结果中随机返回空列表,但计数仍然正确

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,

当我尝试使用自定义过滤器时,它在本地开发中一直工作,但当我们部署到生产环境(Docker Swarm)时,我们发现一个问题,即有时API响应随机返回空结果,但计数是正确的。下面是API的示例结果

API响应

{
    '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()