Django-filters не работает с Viewset

Я пытался использовать django-filters, но объекты не фильтруются. Кроме того, разрешение не работает для представлений partial_update.

У меня есть Viewset, который имеет основные действия, такие как - list (), retrieve (), destroy (), partial_update () и несколько других действий, и пытается применить фильтр для того же.

После некоторого исследования я обнаружил, что, поскольку я создаю набор запросов с помощью фильтров, мне придется переопределить метод get_queryset (). Однако это тоже, похоже, не работает. Фильтр работает только с ModelViewSet или ListApiView?

ViewSet -

class PostViewSet(viewsets.ViewSet):
"""
The Endpoint to list, retrieve, create and delete Posts.

"""
filter_backends = (DjangoFilterBackend, )
# filterset_class = PostFilter
filter_fields = ('pet_age', 'pet_gender', 'breed')

def get_permissions(self):

    if self.action == 'partial_update' or self.action == 'update':
        permission_classes = [IsPostAuthor, ]

    elif self.action == 'create' or self.action == 'destroy':
        permission_classes = [IsAuthenticated, ]

    else:
        permission_classes = [AllowAny, ]

    return[permission() for permission in permission_classes]

def get_queryset(self):
    return Post.objects.active() # This is implemented via custom Manager

def list(self, request, *args, **kwargs):
    """
    Method for Post listing. It can be accessed by anyone.
    """

    serializer = PostListSerializer(self.get_queryset(), many=True, context={"request": request})

    return Response(serializer.data)
# REST CODE TRUNCATED

Разрешение -

class IsPostAuthor(permissions.BasePermission):
"""
Object-level permission to only allow owners of an object to edit it.
"""

def has_object_permission(self, request, view, obj):
    if request.user.is_authenticated:
        if view.action in ['partial_update', 'update']:
            return obj.user.id == request.user.id
        return False

    return False

PostFilter -

class PostFilter(filters.FilterSet):

class Meta:
    model = Post
    fields = ('pet_age', 'pet_gender', 'breed', )

Менеджер -

class PostManager(models.Manager):

def active(self):
    return self.filter(post_status='Active')

Любая помощь будет принята с благодарностью.


person 5parkp1ug    schedule 17.09.2018    source источник
comment
Что вы имеете в виду под разрешением не работает? Похоже, вы не добавили IsPostAuthor в представление   -  person JPG    schedule 17.09.2018
comment
Я проверяю разрешение на основе действия просмотра, т.е. хочу ограничить доступ к методу partial_update () для пользователя, создавшего сообщение (автора). Для этого я переопределил _ get_permissions () _, как указано в документы   -  person 5parkp1ug    schedule 17.09.2018


Ответы (2)


Итак, наконец-то нашел решение из DRF Docs . Проблема заключалась в том, что в случае обычного ViewSet вам необходимо переопределить метод filter_queryset () и вернуть соответствующий queryset соответственно. Затем используйте queryset в разделе filter_queryset, как указано Aman -

serializer = PostListSerializer(self.filter_queryset(self.get_queryset()), many=True, context={"request": request})

Ниже приведен код для справки для тех, кто все еще сталкивается с проблемами -

filter_queryset -

def filter_queryset(self, queryset):
    filter_backends = (DjangoFilterBackend, )

    # Other condition for different filter backend goes here

    for backend in list(filter_backends):
        queryset = backend().filter_queryset(self.request, queryset, view=self)
    return queryset
person 5parkp1ug    schedule 18.09.2018
comment
не могли бы вы поделиться полным набором просмотров с перекрытым набором запросов - person Harry Moreno; 25.02.2019

Вы перезаписали метод списка, поэтому он не работает, вызывая метод filter_queryet.

def list(self, request, *args, **kwargs):
    """
     Method for Post listing. It can be accessed by anyone.
     """

    serializer = PostListSerializer(self.filter_queryset(self.get_queryset()), many=True, context= . 
     {"request": request})

    return Response(serializer.data)
person aman kumar    schedule 18.09.2018
comment
Спасибо за ответ. Однако метод filter_queryset () реализован в рамках PostFilter, поэтому мы не можем ссылаться на него как на self.filter_queryset (). Кроме того, я попытался переопределить этот метод, но это тоже не сработало. Я думал, связано ли это с ViewSet. Должен ли я реализовать представление через ModelViewSet ?? - person 5parkp1ug; 18.09.2018
comment
github.com/encode/django-rest-framework/ blob / master /, см. ListModelMixin, он вызывает self.filter_queryset (self.get_queryset ()) - person aman kumar; 19.09.2018
comment
Да, но я не использовал миксин. В любом случае проблема решена. Тем не менее, спасибо за вклад. - person 5parkp1ug; 19.09.2018
comment
viewsets.ViewSet - это класс, использующий эту смесь - person aman kumar; 19.09.2018