分类
利用django-filters来实现分类功能比较简单,步骤如下:
- 首先安装django-filters:
pip install django-filter
- 在相应的视图里面导入django_filters包,定义filter_backends和filter_fields,例如,按课程的标签进行分类,我们有如下代码:
from .models import Course
from .serializers import CourseModelSerializer
from django_filters.rest_framework import DjangoFilterBackend
class CourseListAPIView(ListAPIView):
queryset = Course.objects.filter(is_show=True, is_delete=False).order_by("orders", "-id")
serializer_class = CourseModelSerializer
filter_backends = [DjangoFilterBackend, ]
filter_fields = ('course_category', )
其中,filter_fields中放的是这个视图表中的字段。血泪教训这两个新加的变量,一定不要拼错啊,比如说少加了变量名后面的s。
- get请求就通过在url后面加参数的方式就能够获取到分类的结果了,比如:
host:port/course/?course_category=6
得到的结果就是课程类别为6的分类结果
- 前端则通过vue中的watch字段来course_category变量进行监听,值一旦发生改变,就调用get请求,并附带相应的参数,得到分类结果,watch的用法值得关注一下:
watch:{
category(){
this.get_course()
}
},
排序
排序的思路和分类差不多,都是前端发送排序/分类的请求,后端进行处理之后将排序的结果返回给前端。
- django自带排序的过滤器OrderingFilter:
from .models import Course
from .serializers import CourseModelSerializer
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import OrderingFilter
class CourseListAPIView(ListAPIView):
"""
课程信息
"""
queryset = Course.objects.filter(is_show=True, is_delete=False).order_by("orders", "-id")
serializer_class = CourseModelSerializer
filter_backends = [DjangoFilterBackend, OrderingFilter]
filter_fields = ('course_category', )
ordering_fields = ('id', 'students', 'price', )
在分类的基础上,添加OrderingFilter到filter_backends中,指定可以按照那些字段进行排序,也就是定义ordering_fields
- get请求时,在url后面加上ordering=ordering_fields中的字段便可得到相应的排序结果,例如:
host:port/course/?ordering=id
- 前端根据排序的方法记录,发送相应的请求:
get_course(){
let filters={
}
if(this.filter.orders=="asc"){
filters.ordering = '-'+this.filter.type
}else{
filters.ordering = this.filter.type
}
if(this.category>0){
filters.course_category = this.category
// console.log(this.category)
}
// 获取课程信息
this.$axios.get(`${this.$settings.HOST}/course/`, {
params:filters
}).then(response=>{
this.course_list = response.data;
}).catch(error=>{
console.log(error.response);
})
}
- 展示结果
分页
Rest framework中有PageNumberPagination、Element-UI中有el-pagination,结合这两个组件,一个实现后端、一个现实前端。
- 后端
后端导入PageNumberPagination这个类,然后继承它,配置页面大小、最大页面大小后,就可以像前面说的分类、排序的方法,通过url来控制分页数据了:
#分页器是放在列表视图中的
from rest_framework.pagination import PageNumberPagination
class CoursePageNumberPagination(PageNumberPagination):
"""课程列表的分页器"""
page_query_param = "page" # 地址上面代表页码的变量名,默认为page
page_size = 2 # 每一页显示的数据量,默认是10条, 没有设置页码,则不进行分页
# 允许客户端通过指定的参数名来设置每一页数据量的大小,默认是size
page_size_query_param = "size"
max_page_size = 20 # 限制每一页最大展示的数据量
###下面这一句是放在视图里面的!!!!
class CourseListAPIView(ListAPIView):
pagination_class = CoursePageNumberPagination
根据上面的代码,当我们访问http://127.0.0.1:8000/course/?size=1&page=2
时,将页面大小设置为1,获取第二页的数据。
- 前端
Element-UI的组件可以获得用户设置的页码和每页的最大数据:
<el-pagination
background
layout="prev, pager, next, sizes, jumper"
:page-size="filter.size"
:page-sizes="[1, 2, 3, 5, 10]"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
:total="total">
</el-pagination>
- layout:设置分页器组件的子组件有哪些,如下图
- page-size:设置页面的大小,获得值,可传给后端
- page-sizes:设置页面大小的可选项
- current-change:当点击prev、pager、next或是修改jumper值之后操作,这就是hook、回调!
- size-change:设置page-sizes具体是哪个值,设置之后重新发送请求
如此一组合,便实现了前后端的分页功能