vue_drf之多级过滤、排序、分页
一、前端代码
1,父组件free_course.vue
<template> <div id="free_course"> <el-container> <el-header class="header"><Header :current_state="current_state"/></el-header> <div style="background-color: #f6f6f6"> <div> <Filters @url="url_change"/> </div > <div v-for="item in info"> <content_free :item="item"/> </div> <el-pagination @current-change="handleCurrentChange" background layout="prev, pager, next" :page-size="page_size" :current-page.sync="current_page" :total=total> </el-pagination> </div> <div class="nothing" v-show="info.length==0"></div> <div class="nothing1" v-show="info.length==1"></div> <Footer/> </el-container> </div> </template> <script> import Header from '../common/header' import Footer from '../common/footer' import Filters from './filter' import content_free from './content_free' export default { name:'free_course', data:function () { return { page:2, info:[], current_state:1, total:10, page_size:1, current_page:1, params:'', url:'http://127.0.0.1:8000/course/course' } }, components:{ Header,Footer,Filters,content_free }, methods:{ handleCurrentChange(val){ // 名字必须固定 let url = this.url; url+="?page="+val+"&page_size="+this.page_size+'&'+this.params; this.$axios.get(url).then(res=>{ this.info = res.data.results; this.total =res.data.count; }).catch(error=>{ console.log(error.response); }) }, url_change:function (params) { this.params=params; this.current_page=1; this.handleCurrentChange(1); } }, created:function () { this.handleCurrentChange(1) } } </script>
父组件的css
<style scoped> .el-header,.el-footer{ padding: 0; } .el-header{ height: 80px !important; } .el-pagination{ width: 380px; margin: 0 auto; } .nothing{ height: 519px; background-color: rgb(246, 246, 246) } .nothing1{ height: 229px; background-color: rgb(246, 246, 246) } </style>
2,子组件filter.vue
<template> <div id="filter"> <div class="filter"> <el-row :gutter="5"> <el-col :span="3"><span>学科分类:</span></el-col> <el-col :span="3"><span class="selected" @click="all($event,'course_category',0)">全部</span></el-col> <el-col v-for="item in info " :span="3" > <span @click="single($event,'course_category',item.id,0)">{{item.name}}</span> </el-col> </el-row> <el-row> <el-col :span="3"><span>筛 选:</span></el-col> <el-col :span="3"><span class="selected" @click="all($event,'ordering',1)">默认</span></el-col> <el-col :span="3"><span @click="single($event,'ordering','-students',1)">人气</span></el-col> <el-col :span="3"><span class="tubiao"><span class="left">价格</span><i class="el-icon-caret-top top" :style='tubiao_status==1 ? ss :""' @click="price($event,'ordering','-price',1)"></i><i class="el-icon-caret-bottom bottom" :style='tubiao_status==2 ? ss :""' @click="price($event,'ordering','price',2)"></i></span></el-col> </el-row> </div> </div> </template> <script> export default { name:'Filters', data:function () { return { info:[], url_dict:{}, tubiao_status:'', ss:{ color:'#ffc210', }, } }, methods:{ url:function(){ let params=''; for (let item in this.url_dict){ params=params+`${item}=${this.url_dict[item]}&` } this.$emit('url',params); }, price:function(event,type,value,num){ this.url_dict[type]=value; this.tubiao_status=num; this.url(); let target=event.currentTarget; let parenttarget=target.parentElement.parentElement.parentElement.children; for(let item in parenttarget){ if (parenttarget[item].firstElementChild){ parenttarget[item].firstElementChild.classList.remove('selected'); } } }, selected:function (event) { let target=event.currentTarget; let parenttarget=target.parentElement.parentElement.children; for(let item in parenttarget){ if (parenttarget[item].firstElementChild){ parenttarget[item].firstElementChild.classList.remove('selected'); } } target.classList.add('selected'); }, all:function (event,type,num) { this.selected(event); delete this.url_dict[type]; if (num==1){ this.tubiao_status=''; } this.url() }, single:function (event,type,value,num) { this.selected(event); this.url_dict[type]=value; if (num==1){ this.tubiao_status=''; } this.url() }, }, created:function () { let _this=this; this.$axios.get('http://127.0.0.1:8000/course/courseclassify/') .then(function (res) { _this.info=res.data; }).catch(function (error) { console.log(error.response) }) } } </script>
子组件的css
<style scoped> .filter{ width: 1060px; height: 150px; margin: 0 auto; background-color: white; padding: 20px; margin-top: 20px; } .selected{ padding: 6px 16px; color: #ffc210; border: 1px solid #ffc210!important; border-radius: 30px; } .el-row{ margin-top: 20px; } .tubiao{ position: relative; display: inline-block; height: 22px; } .tubiao .top{ position: absolute; top: 0; left: 34px; cursor: pointer; } .tubiao .bottom{ position: absolute; bottom: 0; left: 34px; cursor: pointer; } .tubiao .left{ position: absolute; left: 0; top: 0; width: 32px; cursor: default; } .el-col>span{ cursor: pointer; } </style>
二、后端代码
settings.py配置
REST_FRAMEWORK = { #过滤组件 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend', # 解决过滤组件和排序组件之间的覆盖问题 'rest_framework.filters.OrderingFilter'), }
views.py
class StandardPageNumberPagination(PageNumberPagination):
page_size_query_param = 'page_size'
max_page_size = 1
class CourseView(ListAPIView): queryset = Course.objects.filter(status=0,is_delete=False).order_by('orders') serializer_class = CourseModelSeralizer #设置过滤字段 filter_fields = ('course_category',) #必须把这个删掉,它和后面的排序字段冲突 # filter_backends = [OrderingFilter] ordering_fields = ('id', 'students', 'price') pagination_class = StandardPageNumberPagination
serializer.py
from rest_framework import serializers from .models import * class CourseClassifyModelSerializer(serializers.ModelSerializer): class Meta: model=CourseClassify fields=('id','name',) class TeacherModelSerializer(serializers.ModelSerializer): class Meta: model=Teacher fields=['name','role','image','brief'] class CourseLessonModelSerializer(serializers.ModelSerializer): class Meta: model=CourseLesson fields = [ 'name', 'section_link','duration','free_trail','orders'] class CourseChapterModelSerializer(serializers.ModelSerializer): coursesections=CourseLessonModelSerializer(many=True) class Meta: model=CourseChapter fields=['chapter','name','coursesections'] class PriceServicesModelSerializer(serializers.ModelSerializer): """价格服务策略序列化器""" class Meta: model = PriceService fields = ("condition","sale",'remaintime') class PriceServiceTypeModelSerializer(serializers.ModelSerializer): """价格服务类型序列化器""" priceservices = PriceServicesModelSerializer(many=True) # priceservices 价格策略 class Meta: model = PriceServiceType fields = ("id","name","priceservices") class CourseModelSeralizer(serializers.ModelSerializer): teacher=TeacherModelSerializer() coursechapters=CourseChapterModelSerializer(many=True) price_service_type=PriceServiceTypeModelSerializer() class Meta: model=Course fields=['id','name','course_img','students','brief_url','levels','lessons','pub_lessons','price','teacher','coursechapters','price_service_type','current_price']