Как вернуть пустой набор запросов из django_filters.FilterSet в представлении API, если строка запроса не содержит ни одного правильного ключа

Я использую пакет django-filter с пакетом djangorestframework для фильтрации объектов, которые возвращаются из представления API. Вот мои файлы:

# models.py
class Symbol(models.Model):
    title = models.CharField(max_length=30, verbose_name='title')
    

# serializers.py
class SymbolSerializer(serializers.ModelSerializer):
    class Meta:
        model = Symbol
        fields = ('title',)

    
# filters.py
class SymbolFilter(django_filters.FilterSet):
    st = django_filters.CharFilter(method='get_st', label='search')

    def get_st(self, queryset, field_name, value):
        return queryset.filter(title__icontains=value)

    class Meta:
        model = Symbol


# views.py 
@api_view(['GET'])
def symbol_list(request):
    queryset = Symbol.objects.all()
    view_filter = APIFilters.APISymbolFilter(request.GET, queryset=queryset)
    if (view_filter.is_valid() is False) or (not view_filter.qs):
        return Response(None, status=status.HTTP_404_NOT_FOUND)

    ser = SymbolSerializer(view_filter.qs, many=True)
    return Response(ser.data, status=status.HTTP_200_OK)


# urls.py 
from .views import * 
urlpatterns = [
    path('symbol/list/', symbol_list, name='symbol_list'),
]   

Итак, если я посылаю get запрос к localhost:8000/symbol/list/?st=sometitle, все хорошо, и я получу Symbol объекты, которые имеют sometitle в поле title. Но когда я удалю st из querystring, django-filter вернет все объекты в модели Symbol. Мой вопрос заключается в следующем:

Как вернуть пустой набор запросов, если ключ st отсутствует в querystring или если filter(title__icontains=value) был пуст?

Вы можете использовать none() метод:

def get_st(self, queryset, field_name, value):
    if not value:
        return queryset.none() 
    return queryset.filter(title__icontains=value)

Я предполагаю, что по умолчанию, если параметр запроса st не установлен, вы хотите вернуть пустой список. Если это так, то вы можете сделать следующее.


@api_view(['GET'])
def symbol_list(request):
    # check if st is set
    if request.GET.get("st", None):
       queryset = Symbol.objects.all()
    else:
       queryset = Symbol.objects.none()
    view_filter = APIFilters.APISymbolFilter(request.GET, queryset=queryset)
    if (view_filter.is_valid() is False) or (not view_filter.qs):
        return Response(None, status=status.HTTP_404_NOT_FOUND)

    ser = SymbolSerializer(view_filter.qs, many=True)
    return Response(ser.data, status=status.HTTP_200_OK)

Вернуться на верх