python-blog's People
python-blog's Issues
drf rest过滤方法总结
传统的过滤方法
User.object.filter(name='xxx')
url过滤
path('<str:name>/vote/', vote_list, name='vote_list')
......
class ListExample(mixins.ListModelMixin):
serializer_class = UserSerializers
def get_querySet(self):
nm = self.kwarg['name']
return User.object.filter(name=nm)
url查询参数过滤
http://example.com/api/user?name=xxx
......
param = self.request.query_params('name', None)
querySet = User.object.filter(name=params)
Django-Filter过滤
简单过滤
setting.py中设置如下:
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}
view.py代码:
filter_backends = (DjangoFilterBackend,)
filter_fields = ['name']
若是在admin中需要使用,安装django-crispy-forms
filterSet过滤
有时,简单的过滤方式无法实现我们的业务要求,需要自己定义过滤方法
class RangeWidget(DateRangeWidget):
suffixes = ['from', 'to']
class FormFilter(django_filters.rest_framework.FilterSet):
name = django_filters.CharFilter(field_name='game__name', lookup_expr='icontains')
source = django_filters.CharFilter(field_name='game__source', lookup_expr='icontains')
num = django_filters.NumberFilter(field_name='num', lookup_expr='gte')
time = django_filters.DateFilter(field_name='pub_time')
range = django_filters.DateTimeFromToRangeFilter(field_name='pub_time', widget=RangeWidget)
class Meta:
models = Post
fields = ['name', 'source', 'num', 'pub_time', 'pub_time']
class PostView(mixins.ListModelMixin, GenericViewSet):
"""
list:
post列表
"""
queryset = Post.objects.all()
serializer_class = PostSerializer
pagination_class = PostPagination
filter_backends = (DjangoFilterBackend,)
filter_class = FormFilter
这里需要查看django-filter的文档
一般字符和数字的过滤很简单
过滤关键字
- field_name:模型字段名称,外键关联字段可以通过双下划线(__)方式获取;
- look_exrp:执行字段查找的方式,和django中的字段查找方法一样
此外还有method、lable、**kwarg、widget、distinct和exclude
详细参考相关文档
过滤器
除CharFilter和NumberFilter之外,还有很多如BooleanFilter、ChoiceFilter、DateFilter、TimeFilter、DateTimeFilter等
以上基本都是精准匹配,若是对于范围匹配,需要使用如下过滤器:
RangeFilter、DateRangeFilter、DateFromToRangeFilter、DateTimeFromToRangeFilter
以上代码有使用的方式,若是使用range类型的话,默认是在字段后匹配0和1
GET /products?price_0=10&price_1=25 HTTP/1.1
我们可以自己设置后缀,这里就要使用到小部件RangeWidget
from django_filters.widgets import SuffixedMultiWidget
class RangeWidget(SuffixedMultiWidget):
suffixes = ['min', 'max']
class FormFilter(FilterSet):
range = django_filters.RangeFilter(field_name='name', widget=RangeWidget)
class Meta:
fields = ['name']
但是对时间这块,由于源码中时间过滤器如下:
class DateFromToRangeFilter(RangeFilter):
field_class = DateRangeField
class DateTimeFromToRangeFilter(RangeFilter):
field_class = DateTimeRangeField
class IsoDateTimeFromToRangeFilter(RangeFilter):
field_class = IsoDateTimeRangeField
class TimeRangeFilter(RangeFilter):
field_class = TimeRangeField
当我们alt点击每个的***Field类(如DateRangeField)时,实现如下
class IsoDateTimeRangeField(RangeField):
widget = DateRangeWidget
def __init__(self, *args, **kwargs):
fields = (
IsoDateTimeField(),
IsoDateTimeField())
super().__init__(fields, *args, **kwargs)
可以发现widget默认为DateRangeWidget, 再看看DateRangeWidget的源码:
class DateRangeWidget(RangeWidget):
suffixes = ['after', 'before']
所以我们在定义时间之类的range时,默认后缀为after和before,如果想要修改,修改的方式如下:
class RangeWidget(DateRangeWidget):
suffixes = ['from', 'to']
......
range = django_filters.DateTimeFromToRangeFilter(field_name='pub_time', widget=RangeWidget)
# url
http://127.0.0.1:8000/spider/post?range_from=2019-06-09+00:00:00&range_to=2019-06-11+00:00:00
搜索过滤
这种方式和本质上的过滤没有区别,主要使用SearchFilter类
class PostView(mixins.ListModelMixin, GenericViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
pagination_class = PostPagination
filter_backends = (DjangoFilterBackend, SearchFilter,)
filter_class = FormFilter
search_fields = ('=username', '@email')
同样的,使用双下划线符号对ForeignKey或ManyToManyField执行相关查找
-
'^' 以指定内容开始.
-
'=' 完全匹配
-
'@' 全文搜索(目前只支持Django的MySQL后端)
-
'$' 正则搜索
若是要排序搜索使用 OrderingFilter
filter_backends = (filters.OrderingFilter,)
# 指定字段搜索排序
ordering_fields = ('username', 'email')
# 默认字段搜索排序
ordering = ('username',)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.