Django 5 для начинающих

Прогресс по курсу:  9/1004

8.5 Фильтрация, поиск
5 из 5 шагов пройдено

Фильтрация

Стандартным поведением общих представлений списка в DRF является возврат всего набора запросов для менеджера модели. Часто вы хотите, чтобы ваш API ограничивал элементы, возвращаемые набором запросов.
Самый простой способ отфильтровать QuerySet любого представления, подкласса GenericAPIView, - это переопределить метод .get_queryset().
Переопределение этого метода позволяет вам настраивать QuerySet, возвращаемый представлением, различными способами.


Фильтрация по текущему пользователю

Вы можете захотеть отфильтровать набор запросов, чтобы гарантировать, что будут возвращены только результаты, относящиеся к текущему аутентифицированному пользователю, сделавшему запрос.
Это можно сделать с помощью фильтрации на основе значения request.user, изменим код класса в views.py

from rest_framework import generics
from blog.models import Post
from .serializers import PostSerializer


class PostList(generics.ListCreateAPIView):
    # queryset = Post.objects.all()
    serializer_class = PostSerializer

    def get_queryset(self):
        user = self.request.user
        return Post.objects.filter(author=user)


class PostDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

Проверим работу, для этого авторизуемся как администратор и зайдем на наш API сервис - http://127.0.0.1:8000/api/:

Мы видим что отобразились все посты, где поле author == 1. Теперь попробуем выйти из под администратора и зайти под другим пользователем. И увидим что данный список Post List будет пуст.


  • Комментариев
Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий

Но при этом, если выйти из под администратора и зайти под другим пользователем, на скрине видна HTML form, где можно создать пост и он создается...
Как запретить такое поведение?

@Anonymous_450292901, в разделе 9.7 мы это исправим, изменив права доступа.

Здесь избыточность:

В предыдущем разделе сказано, что нужно или задать queryset, или определить метод get_queryset().
Без второй строки работает так же

Дополнил - в следующем уроке нужно закомментировать метод, т.ч. вторая строка пригодится. Но можно держать раскомментированной только одну

Изменен ilya kutaev

@ilya_kutaev, Спасибо, в этом шаге я закомментировал queryset, и в следующем шаге добавил чтобы его раскомментировали, но закомментировали метод get_queryset().

Вы можете захотеть отфильтровать набор запросов, чтобы гарантировать, что будут возвращены только результаты, относящиеся к текущему аутентифицированному пользователю, сделавшему запрос.

То есть смысл нашего API в том, что у пользователя есть некий программный интерфейс который по запросу к нашему API может получать информацию о всех постах и использовать например у себя на сайте? 

@Георгий_Тимофеев, да, например может использоваться в мобильном приложении.

у меня админ под числом 2 не понятно почему? Подскажите почему так вышло?

"author": 2,

@No_Name, А в админ панели сколько пользователей? Может у вас 2 админа создано?

такая же ситуация и тут нет призыва к тому что надо переопределять нашу вьюшку

 

Фильтрация по текущему пользователю

Вы можете захотеть отфильтровать набор запросов, чтобы гарантировать, что будут возвращены только результаты, относящиеся к текущему аутентифицированному пользователю, сделавшему запрос.
Это можно сделать с помощью фильтрации на основе значения request.user:

from rest_framework import generics
from blog.models import Post
from .serializers import PostSerializer


class PostList(generics.ListCreateAPIView):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

    def get_queryset(self):
        user = self.request.user
        return Post.objects.filter(author=user)


class PostDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

@No_Name, добавил