The filter assembly rest framework

An ordinary filter

1、get_queryset

  get_queryset method is a method GenericAPIView provided, designed to return queryset data sets, and return filter is to filter the data before the data set in this method, then returns the filtered data can then also need to override this method is to ask :

    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

This method in the source code obtained from queryset view configuration, and determines whether QuerySet type, if they are, it will return to this queryset.

2, examples

  • Request API
class BookView(GenericViewSet):

    serializer_class = BookModelSerializer

    def get_queryset(self):
        queryset = models.Book.objects.all()
        title = self.request.query_params.get('title',None)
        if title is not None:
            queryset = models.Book.objects.filter(title=title).all()
        return queryset

    def list(self,request,*args,**kwargs):
        queryset= self.get_queryset()
        bs=self.get_serializer(queryset,many=True)
        return Response(bs.data)

Routing configuration:

Note that if necessary filtered, url attribute required base_name added, and the value of the filter base_name name of the parameter is:

router=routers.DefaultRouter()
router.register('books',views.BookView,base_name="title")

The resulting route:

^books/$ [name='title-list']
^books\.(?P<format>[a-z0-9]+)/?$ [name='title-list']

Request Address:

    http://127.0.0.1:8020/books/?title= language

 Second, advanced filtering

  • Install django-filter
pip install django-filter
  • Registration django-filter
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config',
    'rest_framework',
    'django_filters',  #注册django-filter
]
  • Setting common back-end filtration

1, the global configuration

REST_FRAMEWORK = {

    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)

}

2, a partial view of a set

import django_filters.rest_framework 

class BookView(GenericViewSet):

    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializer
    filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
  • Specify the filter field

If demand are some simple types of screening, you can set a filter_fields property in view or viewSet which lists all set fields rely on screening.

import django_filters.rest_framework
from rest_framework.viewsets import ModelViewSet

class BookView(ModelViewSet):

...    
    filter_fields = ('title',) #列出搜索字段
...
  • Access

1, routing configuration

from rest_framework import routers
router=routers.DefaultRouter()
router.register('books',views.BookView) #无需base_name参数
urlpatterns = [
        re_path('',include(router.urls)),
]

2, the generated route

^books/$ [name='book-list']
^books\.(?P<format>[a-z0-9]+)/?$ [name='book-list']
^books/(?P<pk>[^/.]+)/$ [name='book-detail']
^books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='book-detail']

3, visit

http://127.0.0.1:8020/books/?title= language
  • FilterSet

Field above mean one relationship, the foreign key and does not involve the many-field, or if there is a foreign key-many relationships, may be used in the filter_fields '__' of crossing:

class BookView (ModelViewSet): 

    QuerySet = models.Book.objects.all () 
    serializer_class = BookModelSerializer 
    filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
     # listed in the search field, which is publish__name ForeignKey field, authors__name ManyToMany field is 
    filter_fields = ( ' title ' , ' publish__name ' , ' authors__name ' )
class Book(models.Model):
    title=models.CharField(max_length=32)
    price=models.IntegerField()
    pub_date=models.DateField(null=True,blank=True)
    publish=models.ForeignKey("Publish",on_delete=models.CASCADE)
    authors=models.ManyToManyField("Author")
    def __str__(self):
        return self.title
models

At this request Address:

 # Containing the foreign key 
http://127.0.0.1:8020/books/?title= Language & publish__name = Beijing Publishing House 

# containing many- 
http://127.0.0.1:8020/books/?title= Language & publish__name = Beijing Publishing social & authors__name = Joe Smith

However, part of the so-many foreign key and the double underlined Django agreed as an API exposed. To explicitly named filter parameters, it can be explicitly included in the class FilterSet:

1, the definition of class FilterSet

import django_filters
from app01 import models

class BookFilter(django_filters.rest_framework.FilterSet):
    publish = django_filters.CharFilter(field_name="publish__name")
    authors = django_filters.CharFilter(field_name="authors__name")
    class Meta:
        model = models.Book
        fields = ['title', 'publish', 'authors']

2, using a defined class in the view FilterSet

class BookView(ModelViewSet):

    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializer
    filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
    filter_class = BookFilter #使用定义的FilterSet类

At this request Address:

http://127.0.0.1:8020/books/?title= Language & publish = Beijing Press & authors = Joe Smith

3, summary

FilterSet can achieve more complex filtering function, the field may be used if an ordinary filter filter_fields add fields, if there is a foreign key, and many-range (range date, price ranges) used FilterSet.

 Third, other

1, the search filter (SearchFilter)

Support based on simple search query parameters, and based on Django admin search feature.

  • Set the back-end filtration
from rest_framework import filters

class BookView(ModelViewSet):

...
    filter_backends = (filters.SearchFilter,)
...
  • Set the query field
from rest_framework import filters

class BookView(ModelViewSet):

    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializer
    # filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
    filter_backends = (filters.SearchFilter,)

   #凡是以下字段内容都会被搜到
    search_fields = ('title','publish__name','authors__name')

Of course, you can limit the search behavior by adding various characters in front search_fields:

' ^ ' Starts with the specified content. 

' = ' Exact match 

' @ ' full-text search (currently only supports MySQL backend Django's) 

' $ ' regular search

E.g:

search_fields = ('=title',)
  • Client Access
# The contents of all of the search out of the Beijing Publishing House 
http://127.0.0.1:8020/books/?search= Beijing Press
 # to search for relevant content Joe Smith out 
http://127.0.0.1:8020/books/?search = Joe Smith

Search by keyword search, you can search backend search_fields provide content field.

The default search keyword SearchFilters like to search, you can be overridden by setting SEARCH_PARAM

class BookView(ModelViewSet):
...
    SEARCH_PARAM = 'ss'
...

 2, sorting filter (OrderingFilter)

  • Set the sort filter back-end
from rest_framework import filters

class BookView(ModelViewSet):

...
    filter_backends = (filters.OrderingFilter,)
...
  • Field specifies the sort of support (ordering_fields)
from rest_framework Import Filters 

class BookView (ModelViewSet): 
... 
    filter_backends = (OrderingFilter,) 
    ordering_fields = ( ' title ' , ' ID ' ) # Specify field supports sorting 
...
  • Client Access

By Keyword ordering request data in accordance with what sort of return

# Accordance title sort 
http://127.0.0.1:8020/books/?ordering= title 

# accordance id sort 
http://127.0.0.1:8020/books/?ordering= id
 # accordance id reverse 
http: //127.0. 0.1: 8020 / Books / ordering = -? the above mentioned id 

# on multiple fields to sort 
http://127.0.0.1:8020/books/?ordering=id,title
  • The default sort

If desired the returned data has been sorted, and can be used in view ordering parameters:

from rest_framework import filters

class BookView(ModelViewSet):

    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializer
    filter_backends = (filters.OrderingFilter,)
    ordering_fields = ('title', 'id')
    ordering=('-id',) #默认排序

Client Access:

    http://127.0.0.1:8020/books/

Id that has been returned in reverse order according to the data.

Reference documents: https://q1mi.github.io/Django-REST-framework-documentation/api-guide/filtering_zh/#filtering

 

Guess you like

Origin www.cnblogs.com/shenjianping/p/11511978.html