05 drf 频率限制,filter,django-filter

1 模型层choice字段使用(重点)

  • 模型表:Student表,写接口应该选择继承哪个视图类

  • 推荐使用自动生成路由的方式(继承ViewSetMixin及它的字类)

  • 但是目前来说,你先实现功能即可(至于选择哪个,慢慢体会)

  • choice的使用

    在模型类中使用
        sex = models.SmallIntegerField(choices=((1, '男'), (2, '女'), (3, '未知')), default=1)
        -在视图类中,在序列化类中
        	-get_字段名_dispaly()的方法,该方法获得choice字段对应的数据
    
  • choice的示例

class Student(models.Model):
    name = models.CharField(max_length=32)
    sex = models.SmallIntegerField(choices=((1, '男'), (2, '女'), (3, '未知')), default=1)
    sex = models.SmallIntegerField(choices=choice_sex, default=1)
    age = models.IntegerField()

2 自定义频率类(分析,了解)

2.1如何限制频率

如果没有登录就限制ip,登录了限制用户的唯一id

2.2:自定义频率

from rest_framework.throttling import BaseThrottle
class MyThrottle(BaseThrottle):
    VISIT_RECORD = {}  # 存用户访问信息的大字典
    def __init__(self):
        self.history = None
    def allow_request(self,request,view):
        # 根据ip进行频率限制,每分钟只能访问3次
        # 限制的逻辑
        '''
        #(1)取出访问者ip
        #(2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
        #(3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
        #(4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
        #(5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
        '''
        # (1)取出访问者ip
        # print(request.META)
        ip = request.META.get('REMOTE_ADDR')
        import time
        ctime = time.time()
        # (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问
        if ip not in self.VISIT_RECORD:
            self.VISIT_RECORD[ip] = [ctime, ]
            return True
        self.history = self.VISIT_RECORD.get(ip)
        # (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
        while self.history and ctime - self.history[-1] > 60:
            self.history.pop()
        # (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
        # (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
        if len(self.history) < 3:
            self.history.insert(0, ctime)
            return True
        else:
            return False

    def wait(self):
        # 还剩多长时间能访问
        import time
        ctime = time.time()
        return 60 - (ctime - self.history[-1])

2.3:示例

urls.py

from django.urls import path
from learn import views

urlpatterns = [
    path('books/', views.Book.as_view({'get':'get','post':'post'})),
    path('book/<int:pk>/', views.Book.as_view({'get':'retrieve','put':'put','delete':"delete"})),
    path('publishs/', views.Publish.as_view({'get':'get','post':'post'})),
    path('publish/<int:pk>/', views.Publish.as_view({'get':'retrieve','put':'put','delete':"delete"})),
]


serializer

from . import models
from rest_framework import serializers


class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = ['id','title','price','publish','publish_name']
        extra_kwargs = {
            'id': {'required': False},
            'publish': {'write_only': True},
            'publish_name': {'read_only': True},
        }


class PublishModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Publish
        fields = ['id', 'name', 'addr']
        extra_kwargs = {
            'id': {'required': False},
        }


modles.py

from django.db import models


# Create your models here.

class Book(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish = models.ForeignKey(to='Publish', on_delete=models.SET_NULL, null=True, db_constraint=False)

    @property
    def publish_name(self):
        return {'id': self.publish_id, 'name': self.publish.name, 'addr': self.publish.addr }


class Publish(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)
    addr = models.CharField(max_length=255)

utils.py

from rest_framework.throttling import BaseThrottle
class MyThrottle(BaseThrottle):
    VISIT_RECORD = {}  # 存用户访问信息的大字典
    def __init__(self):
        self.history = None
    def allow_request(self,request,view):
        print(view,'这个是视图函数')
        # 根据ip进行频率限制,每分钟只能访问3次
        # 限制的逻辑
        '''
        #(1)取出访问者ip
        #(2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
        #(3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
        #(4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
        #(5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
        '''
        # (1)取出访问者ip
        # print(request.META)
        ip = request.META.get('REMOTE_ADDR')
        import time
        ctime = time.time()
        # (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问
        if ip not in self.VISIT_RECORD:
            self.VISIT_RECORD[ip] = [ctime, ]
            return True
        self.history = self.VISIT_RECORD.get(ip)
        # (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
        while self.history and ctime - self.history[-1] > 60:
            self.history.pop()
        # (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
        # (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
        if len(self.history) < 3:
            self.history.insert(0, ctime)
            return True
        else:
            return False

    def wait(self):
        # 还剩多长时间能访问
        import time
        ctime = time.time()
        return 60 - (ctime - self.history[-1])


views.py

from . import models
from . import serializer
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet
from . import utils


class Book(ViewSet):
    throttle_classes = [utils.MyThrottle]
    def get(self, request, *args, **kwargs):
        book_obj = models.Book.objects.all()
        ser = serializer.BookModelSerializer(instance=book_obj, many=True)
        return Response(ser.data)

    def retrieve(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        obj = models.Book.objects.get(pk=pk)
        ser = serializer.BookModelSerializer(instance=obj)
        return Response(ser.data)

    def post(self, request, *args, **kwargs):
        ser = serializer.BookModelSerializer(data=request.data)
        ser.is_valid(raise_exception=True)
        ser.save()
        return Response(ser.data)

    def put(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        obj = models.Book.objects.get(pk=pk)
        ser = serializer.BookModelSerializer(instance=obj, data=request.data)
        ser.is_valid(raise_exception=True)
        return Response(ser.data)

    def delete(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        models.Book.objects.filter(pk=pk).delete()
        return Response()


class Publish(ViewSet):

    throttle_classes = [utils.MyThrottle]
    def get(self, request, *args, **kwargs):
        book_obj = models.Publish.objects.all()
        ser = serializer.PublishModelSerializer(instance=book_obj, many=True)
        return Response(ser.data)

    def retrieve(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        obj = models.Publish.objects.get(pk=pk)
        ser = serializer.PublishModelSerializer(instance=obj)
        return Response(ser.data)

    def post(self, request, *args, **kwargs):
        ser = serializer.PublishModelSerializer(data=request.data)
        ser.is_valid(raise_exception=True)
        ser.save()
        return Response(ser.data)

    def put(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        obj = models.Publish.objects.get(pk=pk)
        ser = serializer.PublishModelSerializer(instance=obj, data=request.data)
        ser.is_valid(raise_exception=True)
        return Response(ser.data)

    def delete(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        models.Publish.objects.filter(pk=pk).delete()
        return Response()

3 内置频率类,及其使用

3.1:局部使用

class Test(APIView):
    def get(self,request,*args,**kwargs):
        pass
    throttle_classes = [learn.utils.MyThrottle,]

3.2:局部禁用

class Test(APIView):
    def get(self,request,*args,**kwargs):
        pass
    throttle_classes = []

3.3:全局使用

setings.py

REST_FRAMEWORK = {
    	'DEFAULT_THROTTLE_CLASSES':['learn.auth.MyThrottle',],
		}

3.4:内置频率类

  1. BaseThrottle:基类
  2. AnonRateThrottle:限制匿名用户的访问次数
  3. SimpleRateThrottle:咱么自定义改写它
  4. ScopedRateThrottle:
  5. UserRateThrottle:限制登录用户访问次数

3.5:常用内置频率类使用

全局使用

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ),
    'DEFAULT_THROTTLE_RATES': {
        'anon': '100/day',  
        'user': '1000/day'
    }
}

4:如何自定义频率类

4.1:写一个类,继承SimpleRateThrottle

class MySimpleThrottle(SimpleRateThrottle):
    scope = 'ip' #全局文件中要用,不写报错
    def get_cache_key(self, request, view):
        #以ip限制
        return self.get_ident(request)

setting.py中配置

REST_FRAMEWORK = {
    # 这个是必须要配置,凡是继承了rest-framework的频率类,下面必不可少,如果没有报错
    'DEFAULT_THROTTLE_RATES' : {
        'ip':'10/m'# key跟scope对应,value是一个时间
    }
}

4.2:如何使用自定义频率类

4.2.1:局部使用

class Test(APIView):
    def get(self,request,*args,**kwargs):
        pass
    throttle_classes = [learn.utils.MySimpleThrottle,]

4.2.2:全局使用

REST_FRAMEWORK = {
    	'DEFAULT_THROTTLE_CLASSES':['learn.utils.MySimpleThrottle',],
		}

4.3:频率类源码分析

流程代码

image-20201125221914834

image-20201125222520346

image-20201125222620516

image-20201125222712902

核心代码

1

image-20201128143343052

2

image-20201128144828751

3:image-20201128145009576

image-202011281452018194

image-20201128150638108

5

image-20201128152354806

4.4其他的内置频率类使用

4.4.1:未登录用户全局使用

全局使用

settings.py

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.AnonRateThrottle',
      
    ),
    'DEFAULT_THROTTLE_RATES': {
        'anon': '100/m',  
       
    }
}
局部配置

settings.py

REST_FRAMEWORK = {
  
    'DEFAULT_THROTTLE_RATES': {
        'anon': '100/m',  
       
    }
}

views.py

from rest_framework.throttling import AnonRateThrottle
class Test(APIView):
    class = [AnonRateThrottle,]
    def get(self,request,*args,**kwargs):
        pass
    

4.4.2登录用户

全局使用

settings.py

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.UserRateThrottle'
    ),
    'DEFAULT_THROTTLE_RATES': {
        'user': '1000/day'
    }
}
局部配置

setings

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES': {
        'user': '1000/day'
    }
}

views.py

from rest_framework.throttling import UserRateThrottle
class Test(APIView):
    class = [UserRateThrottle,]
    def get(self,request,*args,**kwargs):
        pass

5扩展其它源码

5.1:AnonRateThrottle源码

image-20201128173739176

5.2:UserRateThrottle源码

image-20201128174355245

5.3:ScopeRateThrottle源码

image-20201128185050309

5.3.1:ScopRateThrottle使用

views.py

from django.shortcuts import render

# Create your views here.

from . import models
from . import serializer
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet


class Book(ViewSet):
    throttle_scope='book' 

    def get(self, request, *args, **kwargs):
        book_obj = models.Book.objects.all()
        ser = serializer.BookModelSerializer(instance=book_obj, many=True)
        return Response(ser.data)

    def retrieve(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        obj = models.Book.objects.get(pk=pk)
        ser = serializer.BookModelSerializer(instance=obj)
        return Response(ser.data)

    def post(self, request, *args, **kwargs):
        ser = serializer.BookModelSerializer(data=request.data)
        ser.is_valid(raise_exception=True)
        ser.save()
        return Response(ser.data)

    def put(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        obj = models.Book.objects.get(pk=pk)
        ser = serializer.BookModelSerializer(instance=obj, data=request.data)
        ser.is_valid(raise_exception=True)
        return Response(ser.data)

    def delete(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        models.Book.objects.filter(pk=pk).delete()
        return Response()



class Publish(ViewSet):
    throttle_scope = 'publish'
    def get(self, request, *args, **kwargs):
        book_obj = models.Publish.objects.all()
        ser = serializer.PublishModelSerializer(instance=book_obj, many=True)
        return Response(ser.data)

    def retrieve(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        obj = models.Publish.objects.get(pk=pk)
        ser = serializer.PublishModelSerializer(instance=obj)
        return Response(ser.data)

    def post(self, request, *args, **kwargs):
        ser = serializer.PublishModelSerializer(data=request.data)
        ser.is_valid(raise_exception=True)
        ser.save()
        return Response(ser.data)

    def put(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        obj = models.Publish.objects.get(pk=pk)
        ser = serializer.PublishModelSerializer(instance=obj, data=request.data)
        ser.is_valid(raise_exception=True)
        return Response(ser.data)

    def delete(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        models.Publish.objects.filter(pk=pk).delete()
        return Response()

setings.py
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.ScopedRateThrottle',
    ],
    'DEFAULT_THROTTLE_RATES': {
        'book': '5/m',
        'publish': '10/m'
    },

}

6 内置,排序,第三方过滤功能

6.1:通过条件筛选结果

筛选是绝对匹配

views.py
from rest_framework.filters import SearchFilter

class Book(ModelViewSet):
    throttle_scope = 'book'
    serializer_class = serializer.BookModelSerializer
    queryset = models.Book.objects.all()
    
    filter_backends =[SearchFilter,]
    search_fields=('name','age') # 表模型中的字段
查询
http://127.0.0.1:8000/book/?search=1

image-20201128203855161

6.2:排序功能

views.py
from rest_framework.filters import SearchFilter,OrderingFilter

class Book(ModelViewSet):
    throttle_scope = 'book'
    serializer_class = serializer.BookModelSerializer
    queryset = models.Book.objects.all()
    
    filter_backends = [OrderingFilter, ]
    ordering_fields=['id','title'] # 表模型中的字段
查询
http://127.0.0.1:8000/book/?ordering=id
http://127.0.0.1:8000/book/?ordering=-id
http://127.0.0.1:8000/book/?ordering=title
http://127.0.0.1:8000/book/?ordering=-title

image-20201128205925031

6.3:第三方筛选

pip3 install django-filter  :最新版本(2.4.0)要跟django2.2以上搭配
views.py
from django_filters.rest_framework import DjangoFilterBackend

class Book(ModelViewSet):
    throttle_scope = 'book'
    serializer_class = serializer.BookModelSerializer
    queryset = models.Book.objects.all()
    
    filter_backends = [DjangoFilterBackend , ]
    filter_fields=['id','title'] # 过滤模型字段

查询
127.0.0.1:8000/book/?title=linux基础&id=1
127.0.0.1:8000/book/?title=linux基础
127.0.0.1:8000/book/?id=1

image-20201128213013215

7 排序和筛选一起来

views.py
from rest_framework.filters import OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend
class Book(ModelViewSet):
    throttle_scope = 'book'
    serializer_class = serializer.BookModelSerializer
    queryset = models.Book.objects.all()


    filter_backends = [OrderingFilter, DjangoFilterBackend]
    ordering_fields = ('id', 'price')
    filter_fields = ['title', 'id']


查询
http://127.0.0.1:8000/book/?title=linux基础&id=1&ordering=-age,-id
http://127.0.0.1:8000/book/?title=linux基础&id=1
http://127.0.0.1:8000/book/?title=linux基础&id=1&ordering=-id
http://127.0.0.1:8000/book/?title=linux基础&id=1&ordering=-age

image-20201128231415204

8:扩展示例

8.1:编写登录接口,匿名用户一分钟访问3次,登录用户一分钟访问10次

views.py

from django.shortcuts import render

# Create your views here.
import uuid

from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import views
from rest_framework import mixins
from . import models
from . import serializer
from . import utils


class Book(viewsets.GenericViewSet,
           mixins.ListModelMixin,
           mixins.CreateModelMixin):
    authentication_classes = [utils.LoginBaseAuthentication,]
    throttle_classes = [utils.LoginThrottle,utils.UnLoginThrottle]
    serializer_class = serializer.BookModelSerializer
    queryset = models.Book.objects.all()


class Login(views.APIView):

    def post(self, request, *args, **kwargs):
        username = request.data.get('username')
        password = request.data.get('password')
        try:
            user_obj = models.UserInfo.objects.get(username=username, password=password)
            token = uuid.uuid4()
            user_obj.token = token
            user_obj.save()
            return Response({'code': 200, 'msg': '登录成功', 'token': token})
        except Exception:
            return Response({'code': 100, 'msg': '用户名或者密码错误'})

urls.py

from django.urls import path
from work import views

urlpatterns = [
    path('login/', views.Login.as_view()),
    path('book/', views.Book.as_view({'get':'list','post':'create'})),
]

modles.py

from django.db import models

# Create your models here.


class Book(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=255)
    price = models.CharField(max_length=255)
    publish = models.ForeignKey(to='Publish',on_delete=models.SET_NULL,db_constraint=False,null=True)


class Publish(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)
    addr = models.CharField(max_length=255)


class UserInfo(models.Model):
    username = models.CharField(max_length=255,unique=True)
    password = models.CharField(max_length=255)
    token = models.CharField(max_length=255,null=True)
    user_type = models.IntegerField(choices=((1,'vip'),(2,'generic')),default=1)

setings.py

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES': {
        'unlogin': '3/m',
        'login':'10/m'
    }
}

utils.py

from rest_framework.authentication import BaseAuthentication
from rest_framework.throttling import SimpleRateThrottle
from rest_framework.exceptions import AuthenticationFailed, Throttled
from . import models


class LoginBaseAuthentication(BaseAuthentication):
    def authenticate(self, request):
        #
        # token = request.data.get('token') or request.GET.get('token')
        #
        # if not token:
        #     # raise AuthenticationFailed('token关键字')
        #     pass
        # try:
        #     user = models.UserInfo.objects.get(token=token)
        #     return user,token
        # except Exception:
        #     raise AuthenticationFailed('用户名或则密码错误!')

        token = request.data.get('token') or request.GET.get('token')

        if token:
            try:
                user = models.UserInfo.objects.get(token=token)
                return user, token
            except Exception as e:
                print(e)
                pass


class LoginThrottle(SimpleRateThrottle):
    scope = 'login'

    def get_cache_key(self, request, view):
        request.id = 0  # 设置了一个标志位
        id = request.user.pk
        if id:  # 如果有值表示登录了
            request.id = id
            return id
        return None


class UnLoginThrottle(SimpleRateThrottle):
    scope = 'unlogin'

    def get_cache_key(self, request, view):

        if request.id:  # 如果用户登录了request.id为True
            return None
        return self.get_ident(request)

serializer

from rest_framework import serializers
from . import models


class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = ['id', 'title', 'price', 'publish', 'publish_id']
        extra_kwargs = {'id': {'required': False},

                        }

    publish = serializers.SerializerMethodField(read_only=True)
    publish_id = serializers.CharField(write_only=True)

    def get_publish(self, obj):
        return {'id': obj.publish.id, 'name': obj.publish.name, 'addr': obj.publish.addr}


class PublishModelSerializer(serializers.ModelSerializer):
    class Meta:
        mode = models.Publish
        fields = ['id', 'name', 'addr']
        extra_kwargs = {
            'id': {'required': False}
        }

8.2 通过内置过滤器实现

​ -http://127.0.0.1:8000/students/?search=金
​ -查询出书名中带金的所有图书

import uuid

from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import views
from rest_framework import mixins
from . import models
from . import serializer
from . import utils
from rest_framework.filters import SearchFilter


class Book(viewsets.GenericViewSet,
           mixins.ListModelMixin,
           mixins.CreateModelMixin):
    authentication_classes = [utils.LoginBaseAuthentication,]
    throttle_classes = [utils.LoginThrottle,utils.UnLoginThrottle]
    serializer_class = serializer.BookModelSerializer
    queryset = models.Book.objects.all()

    filter_backends = (SearchFilter,)
    search_fields = ('id','title','price')
8.3 通过内置排序实现

http://127.0.0.1:8000/book/?ordering=price
​ -按价格升序,降序排列

from rest_framework.filters import SearchFilter,OrderingFilter


class Book(viewsets.GenericViewSet,
           mixins.ListModelMixin,
           mixins.CreateModelMixin):
    authentication_classes = [utils.LoginBaseAuthentication,]
    throttle_classes = [utils.LoginThrottle,utils.UnLoginThrottle]
    serializer_class = serializer.BookModelSerializer
    queryset = models.Book.objects.all()

    filter_backends = (OrderingFilter,)
    ordering_fields = ['price']

8.4 通过django-filter过滤器实现

http://127.0.0.1:8000/book/?title=金瓶没&price=12
​ -查询出符合条件的图书

from django_filters.rest_framework import DjangoFilterBackend

class Book(viewsets.GenericViewSet,
           mixins.ListModelMixin,
           mixins.CreateModelMixin):
    authentication_classes = [utils.LoginBaseAuthentication,]
    throttle_classes = [utils.LoginThrottle,utils.UnLoginThrottle]
    serializer_class = serializer.BookModelSerializer
    queryset = models.Book.objects.all()

    filter_backends = [DjangoFilterBackend, ]
    filter_fields=['title','price']

8.5:通过django-filter和内置排序实现
http://127.0.0.1:8000/students/?title=金瓶没&odering=price

from rest_framework.filters import SearchFilter,OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend

class Book(viewsets.GenericViewSet,
           mixins.ListModelMixin,
           mixins.CreateModelMixin):
    authentication_classes = [utils.LoginBaseAuthentication,]
    throttle_classes = [utils.LoginThrottle,utils.UnLoginThrottle]
    serializer_class = serializer.BookModelSerializer
    queryset = models.Book.objects.all()


    filter_backends = [OrderingFilter, DjangoFilterBackend]
    ordering_fields = ('id', 'price')
    filter_fields = ['title', 'id','price']

9:扩展内置过滤源码(这一段源码看的翻车了)

image-20201129160450696

image-20201129160544957

image-20201129161048508

image-20201129161404369

image-20201201152750932

image-20201129163534151

image-20201129171445008

posted @ 2020-12-29 17:29  为了等  阅读(114)  评论(0编辑  收藏  举报