zoukankan      html  css  js  c++  java
  • 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']
  • 相关阅读:
    使用线程新建WPF窗体(公用进度条窗体)
    WPF--模板选择
    WPF命令(Command)介绍、命令和数据绑定集成应用
    WPF 员工卡条形码
    WPF入门教程系列(二) 深入剖析WPF Binding的使用方法
    R语言——实验5-聚类分析
    R语言——实验5-聚类分析
    Java学习---流与文件
    Java学习---流与文件
    Java学习---异常处理
  • 原文地址:https://www.cnblogs.com/12345huangchun/p/10659638.html
Copyright © 2011-2022 走看看