今天第一个用drf框架写了个简陋的后台, 算是首次尝试前后台分离开发, 接口调试基本完成。 通过这个应用的编写, 慢慢的也认识到了DRF框架的强大, 比如今天又学会了关于过滤的新姿势!
话说之前写过滤一致是这样子的, 比如
def get_object(self):
return Book.objects.filter(author__pk=1)
是不是长得很平平无奇?刚开始学的时候一直是这么写的, 甚至之前了解不够的情况下,只会这么写:
def get_object(self):
return Book.objects.filter(name='三国演义')
这样的话, 当前端想要查询的时候还要后台去解析参数, 有时候针对不同的类需要过滤的话, 那每个地方都得写这么一段
def retrieve(request, *args, **kwargs)
name = self.request.query_params.get('name', None)
if name:
book = Book.objects.filter(name=name).first()
serializer = BookSerializer(book, many=False)
serializer.valid(raiseException=True)
return Response(serializer.data)
else:
raise BadRequestError('error')
看起来老长老长了, 还都是些无效的代码。直到后来看人家的代码, 再在官网上重新看了下, 原来有个东西叫做过滤器!只要在视图类中加入一行代码就OK了, 前提是你得安装Django_filter, 代码就像下面这样:
from rest_framework import mixins, viewsets, filters
from django_filters.rest_framework import DjangoFilterBackend
class BookViewSet(viewsets.GenericViewSet,
mixins.CreateModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.RetrieveModelMixin,
mixins.ListModelMixin):
queryset = Book.objects.all()
filter_backends = (DjangoFilterBackend, filters.SearchFilter)
filter_fields = ('name', 'author__id')
然后你就可以直接通过http://baseurl/api/book?name=三国演义或者http://baseurl/api/book?author__id=1来访问啦, 当然聪明如你肯定也想到了把后面的__id去掉, 前端需要啥自己补上__就OK了。是不是很强大?甚至你可以使用比较的方式例如age__gt=3这种, 只要你的filter_fields传入的字段是对的, 一旦前端传错参数也没啥关系, 就当没有后面那一截就行了。可以说用起来非常的方便了。
那如果你想要有更高级的用法怎么办呢? 答案是你可以使用filterSet进行定制。
class GoodsFilter(django_filters.rest_framework.FilterSet):
min_price = django_filters.NumberFilter(name='shop_price', lookup_expr='gt')
class Meta:
model = Goods
fields = ['min_price']
这样你就可以在视图函数中使用这个过滤器
from .filters import GoodsFilter
class xxView(xxxView):
filter_class = GoodsFilter
就这两行代码, 一个视图函数就完成了, 而从前端来看,依旧是之前的效果和字段, 是不是很嗨皮呢?
与过滤器并提的其实还有排序和分组, 其形式和此类似, 就改天再说咯!