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>
View Code

  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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;选:</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>
View Code

  二、后端代码

  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']

猜你喜欢

转载自www.cnblogs.com/12345huangchun/p/10659638.html
今日推荐