1- # Урок 39. REST Аутентификация, Авторизация, Permissions.
1+ # Урок 39. REST Аутентификация, Авторизация, Permissions, Фильтрация .
22
33![ ] ( https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQ_cLOesie903fmPPbl2YbqawKsycva_owf6Q&usqp=CAU )
44
@@ -377,7 +377,7 @@ from rest_framework import viewsets
377377class UserViewSet (viewsets .ViewSet ):
378378
379379 # Cache requested url for each user for 2 hours
380- @method_decorator (cache_page(60 * 60 * 2 ))
380+ @method_decorator (cache_page(60 * 60 * 2 ))
381381 @method_decorator (vary_on_cookie)
382382 def list (self , request , format = None ):
383383 content = {
@@ -389,14 +389,15 @@ class UserViewSet(viewsets.ViewSet):
389389class PostView (APIView ):
390390
391391 # Cache page for the requested url
392- @method_decorator (cache_page(60 * 60 * 2 ))
392+ @method_decorator (cache_page(60 * 60 * 2 ))
393393 def get (self , request , format = None ):
394394 content = {
395395 ' title' : ' Post title' ,
396396 ' body' : ' Post content'
397397 }
398398 return Response(content)
399399```
400+
400401` cache_page ` декоратор кеширует только ` GET ` и ` HEAD ` запросы, со статусом 200.
401402
402403### Пример использования авторизации в ресурсах
@@ -412,6 +413,138 @@ class SomeModelViewSet(ModelViewSet):
412413
413414Таким образом мы можем добавлять объект юзера при сохранении нашего сериалайзера.
414415
416+ ## Фильтрация
417+
418+ DRF предоставляет нам огромные возможности для фильтрации, практически не дописывая для этого специальный код.
419+
420+ ### SearchFilter
421+
422+ Как и с другими параметрами у нас есть два варианта указания фильтрации, общая для всего проекта, или конкретная для
423+ определённого класса или функции
424+
425+ Для указания общего фильтра на весь проект, необходимо добавить в ` settings.py ` , в переменную ` REST_FRAMEWORK ` :
426+
427+ ``` python
428+ REST_FRAMEWORK = {
429+ ...
430+ ' DEFAULT_FILTER_BACKENDS' : [' rest_framework.filters.SearchFilter' ]
431+ }
432+ ```
433+
434+ Для указания в конкретном классе необходимо использовать аргумент ` filter_backends ` . Принимает коллекцию из фильтров,
435+ например:
436+
437+ ``` python
438+ from rest_framework.filters import SearchFilter, OrderingFilter
439+
440+
441+ class GroupViewSet (ModelViewSet ):
442+ queryset = Group.objects.all()
443+ filter_backends = [SearchFilter, OrderingFilter]
444+
445+ ```
446+
447+ Или же соответсвующий декоратор, для использования в функциях
448+
449+ #### Как пользоваться?
450+
451+ Для использования необходимо добавить в класс параметр ` search_fields `
452+
453+ ``` python
454+ class GroupViewSet (ModelViewSet ):
455+ queryset = Group.objects.all()
456+ filter_backends = [SearchFilter, OrderingFilter]
457+ search_fields = [' name' , ' label' ]
458+ ```
459+
460+ Который так же принимает коллекцию, состоящую из списка полей по которым необходимо производить поиск.
461+
462+ Теперь у нас есть возможность добавить квери параметр ` search= ` (ключевое слово можно поменять через ` settings.py ` , что
463+ бы искать по указанным полям.
464+
465+ Например:
466+
467+ ```
468+ http://127.0.0.1:9000/api/group/?search=Pyt
469+ ```
470+
471+ Результат будет отфильтрован так, что бы отобразить только те данные, у которых хотя бы в одном из указанных полей будет
472+ найдено частичное совпадение, без учёта регистра (lookup icontains).
473+
474+ Если нам необходим более специфический параметр поиска, существует 4 специальных настройки в параметре ` search_fields ` :
475+
476+ - ` ^ ` Поиск только в начале строки
477+ - ` = ` Полное совпадение
478+ - ` @ ` Поиск по полному тексту (работает на основе индексов, работает только для postgres)
479+ - ` $ ` Поиск регулярного выражения
480+
481+ Например:
482+
483+ ``` python
484+ class GroupViewSet (ModelViewSet ):
485+ queryset = Group.objects.all()
486+ filter_backends = [SearchFilter, OrderingFilter]
487+ search_fields = [' =name' , ' ^label' ]
488+ ```
489+
490+ ### OrderingFilter
491+
492+ Точно так же можно добавить ордеринг фильтр, для того, что бы указывать ордеринг в момент запроса через квери
493+ параметр ` ordering= ` (так же можно заменить через ` settings.py ` )
494+
495+ Необходимо указать параметр ` ordering_fields ` , так же принимает коллекцию из полей. Так же может принимать специальное
496+ значение ` __all__ ` , для возможности сортировать по любому полю.
497+
498+ ``` python
499+ class GroupViewSet (ModelViewSet ):
500+ queryset = Group.objects.all()
501+ filter_backends = [SearchFilter, OrderingFilter]
502+ ordering_fields = [' name' , ' label' ]
503+ ```
504+
505+ В квери параметре может принимать символ ` - ` , или список полей через запятую.
506+
507+ Примеры:
508+
509+ ```
510+ http://example.com/api/users?ordering=username
511+
512+ http://example.com/api/users?ordering=-username
513+
514+ http://example.com/api/users?ordering=account,username
515+ ```
516+
517+ ### Свой собственный фильтр
518+
519+ Как и со всем остальным можно написать свой собственный фильтр, для этого необходимо наследоваться от ` rest_framework.filters.BaseFilterBackend `
520+
521+ И описать один метод ` filter_queryset ` , в котором можно описать любую логику.
522+
523+ Например, фильтр, который будет отображать только те объекты, которые принадлежат юзеру.
524+
525+ ``` python
526+ class IsOwnerFilterBackend (filters .BaseFilterBackend ):
527+ """
528+ Filter that only allows users to see their own objects.
529+ """
530+ def filter_queryset (self , request , queryset , view ):
531+ return queryset.filter(owner = request.user)
532+ ```
533+
534+ ## Сложные комплексные фильтры
535+
536+ На самом деле бываю и значительно более сложные фильтры, для которых существуют специальные пекеджи.
537+
538+ Например:
539+
540+ ```
541+ pip install django-filter
542+ pip install djangorestframework-filters
543+ pip install djangorestframework-word-filter
544+ ```
545+
546+ Все они легко настраиваются и значительно расширяют возможность использования фильтров. Изучите их самостоятельно.
547+
415548
416549## Практика
417550
@@ -422,3 +555,5 @@ class SomeModelViewSet(ModelViewSet):
4225553 . Пишем вьюсеты для моделей из модуля, и создаём 2 покупки и 1 возврат, через постман.
423556
4245574 . Пишем собственный токен, который перестаёт действовать через 10 минут.
558+
559+ 5 . Добавляем фильтр, для поиска только для своих покупок если запрос от обычного пользователя, и все если администратор
0 commit comments