day81:luffy:課程分類頁面&課程資訊頁面&指定分類顯示課程資訊&分頁顯示課程資訊

目錄

1.構建課程前端初始頁面

2.course後端的準備工作

3.後端實現課程分類列表介面

4.前端發送請求-獲取課程分類資訊

5.後端實現課程列表資訊的介面

6.前端顯示列表課程資訊

7.按照指定分類顯示課程資訊

8.分頁顯示課程資訊

1.構建課程前端初始頁面

1.創建Course.Vue,並將初始樣式程式碼放入vue文件中

2.為course組件配置路由,用來做前端訪問用的

router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import Course from "@/components/Course"

Vue.use(Router)

export default new Router({
  mode:'history',
  routes: [
    ......
    {
      path: '/course',
      component: Course,
    }
  ]
})

2.course後端的準備工作

1.在app下創建子應用course

python3 ../../manage.py startapp course

2.註冊course應用

INSTALLED_APPS = [
        ...
    'course',
]

3.設計課程表結構

models.py

from django.db import models
from luffyapi.utils.models import BaseModel
# Create your models here.
class CourseCategory(BaseModel):
    """
    課程分類
    """
    name = models.CharField(max_length=64, unique=True, verbose_name="分類名稱")
    class Meta:
        db_table = "ly_course_category"
        verbose_name = "課程分類"
        verbose_name_plural = "課程分類"


    def __str__(self):
        return "%s" % self.name



class Course(BaseModel):
    """
    專題課程
    """
    course_type = (
        (0, '付費'),
        (1, 'VIP專享'),
        (2, '學位課程')
    )
    level_choices = (
        (0, '初級'),
        (1, '中級'),
        (2, '高級'),
    )
    status_choices = (
        (0, '上線'),
        (1, '下線'),
        (2, '預上線'),
    )
    name = models.CharField(max_length=128, verbose_name="課程名稱")
    course_img = models.ImageField(upload_to="course", max_length=255, verbose_name="封面圖片", blank=True, null=True)
    
    #費用類型欄位是為了後期一些其他功能拓展用的,現在可以先不用,或者去掉它,目前我們項目用不到
    course_type = models.SmallIntegerField(choices=course_type,default=0, verbose_name="付費類型")
    # 這個欄位是課程詳情頁裡面展示的,並且詳情介紹裡面用戶將來可能要上傳一些圖片之類的,所以我們會潛入富文本編輯器,讓用戶填寫數據的時候可以上傳圖片啊、寫標題啊、css、html等等內容
    brief = models.TextField(max_length=2048, verbose_name="詳情介紹", null=True, blank=True)
    
    level = models.SmallIntegerField(choices=level_choices, default=1, verbose_name="難度等級")
    pub_date = models.DateField(verbose_name="發布日期", auto_now_add=True)
    period = models.IntegerField(verbose_name="建議學習周期(day)", default=7)
    
    #課件資料的存放路徑
    attachment_path = models.FileField(max_length=128, verbose_name="課件路徑", blank=True, null=True)
    status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="課程狀態")
    course_category = models.ForeignKey("CourseCategory", on_delete=models.CASCADE, null=True, blank=True,verbose_name="課程分類")
    students = models.IntegerField(verbose_name="學習人數",default = 0)
    lessons = models.IntegerField(verbose_name="總課時數量",default = 0)
    
    #總課時數量可能10個,但是目前之更新了3個,就跟小說、電視劇連載似的。
    pub_lessons = models.IntegerField(verbose_name="課時更新數量",default = 0)
    
    #課程原價
    price = models.DecimalField(max_digits=6,decimal_places=2, verbose_name="課程原價",default=0)
    teacher = models.ForeignKey("Teacher",on_delete=models.DO_NOTHING, null=True, blank=True,verbose_name="授課老師")
    class Meta:
        db_table = "ly_course"
        verbose_name = "專題課程"
        verbose_name_plural = "專題課程"

    def __str__(self):
        return "%s" % self.name



class Teacher(BaseModel):
    """講師、導師表"""
    role_choices = (
        (0, '講師'),
        (1, '導師'),
        (2, '班主任'),
    )
    name = models.CharField(max_length=32, verbose_name="講師title")
    role = models.SmallIntegerField(choices=role_choices, default=0, verbose_name="講師身份")
    title = models.CharField(max_length=64, verbose_name="職位、職稱")
    signature = models.CharField(max_length=255, verbose_name="導師簽名", help_text="導師簽名", blank=True, null=True)
    image = models.ImageField(upload_to="teacher", null=True, verbose_name = "講師封面")
    brief = models.TextField(max_length=1024, verbose_name="講師描述")

    class Meta:
        db_table = "ly_teacher"
        verbose_name = "講師導師"
        verbose_name_plural = "講師導師"

    def __str__(self):
        return "%s" % self.name


class CourseChapter(BaseModel):
    """課程章節"""
    course = models.ForeignKey("Course", related_name='coursechapters', on_delete=models.CASCADE, verbose_name="課程名稱")
    chapter = models.SmallIntegerField(verbose_name="第幾章", default=1)
    name = models.CharField(max_length=128, verbose_name="章節標題")
    summary = models.TextField(verbose_name="章節介紹", blank=True, null=True)
    pub_date = models.DateField(verbose_name="發布日期", auto_now_add=True)

    class Meta:
        db_table = "ly_course_chapter"
        verbose_name = "課程章節"
        verbose_name_plural = "課程章節"

    def __str__(self):
        return "%s:(第%s章)%s" % (self.course, self.chapter, self.name)


class CourseLesson(BaseModel):
    """課程課時"""
    section_type_choices = (
        (0, '文檔'),
        (1, '練習'),
        (2, '影片')
    )
    chapter = models.ForeignKey("CourseChapter", related_name='coursesections', on_delete=models.CASCADE,verbose_name="課程章節")
    name = models.CharField(max_length=128,verbose_name = "課時標題")
    #orders = models.PositiveSmallIntegerField(verbose_name="課時排序") #在basemodel裡面已經有了排序了
    section_type = models.SmallIntegerField(default=2, choices=section_type_choices, verbose_name="課時種類")
    section_link = models.CharField(max_length=255, blank=True, null=True, verbose_name="課時鏈接", help_text = "若是video,填vid,若是文檔,填link")
    duration = models.CharField(verbose_name="影片時長", blank=True, null=True, max_length=32)  # 僅在前端展示使用,所以直接讓上傳影片的用戶直接填寫時長進來就可以了。
    pub_date = models.DateTimeField(verbose_name="發布時間", auto_now_add=True)
    free_trail = models.BooleanField(verbose_name="是否可試看", default=False)
    course = models.ForeignKey('Course',related_name='course_lesson',verbose_name='課程',on_delete=models.CASCADE,null=True,blank=True)
    is_show_list = models.BooleanField(verbose_name='是否推薦到課程列表',default=False)
        lesson = models.IntegerField(verbose_name="第幾課時")
    class Meta:
        db_table = "ly_course_lesson"
        verbose_name = "課程課時"
        verbose_name_plural = "課程課時"

    def __str__(self):
        return "%s-%s" % (self.chapter, self.name)

4.執行資料庫遷移

python manage.py makemigrations
python manage.py migrate

5.把當前新增的課程模型註冊到xadmin裡面.

courses/adminx.py

import xadmin

from .models import CourseCategory
class CourseCategoryModelAdmin(object):
    """課程分類模型管理類"""
    pass
xadmin.site.register(CourseCategory, CourseCategoryModelAdmin)


from .models import Course
class CourseModelAdmin(object):
    """課程模型管理類"""
    pass
xadmin.site.register(Course, CourseModelAdmin)


from .models import Teacher
class TeacherModelAdmin(object):
    """老師模型管理類"""
    pass
xadmin.site.register(Teacher, TeacherModelAdmin)


from .models import CourseChapter
class CourseChapterModelAdmin(object):
    """課程章節模型管理類"""
    pass
xadmin.site.register(CourseChapter, CourseChapterModelAdmin)



from .models import CourseLesson
class CourseLessonModelAdmin(object):
    """課程課時模型管理類"""
    pass
xadmin.site.register(CourseLesson, CourseLessonModelAdmin)

3.後端實現課程分類列表介面

1.添加課程分類的測試數據

INSERT INTO `ly_course_category` (`id`,`orders`,`is_show`,`is_deleted`,`created_time`,`updated_time`,`name`)
 VALUES
(1,11,1,0,'2019-08-13 07:08:47.100074','2019-08-13 07:44:05.903782','python'),
(2,0,1,0,'2019-08-13 07:08:51.451093','2019-08-13 07:43:54.558940','go編程'),
(3,3,1,0,'2019-08-13 07:08:57.390196','2019-08-13 07:08:57.390226','Linux運維'),
(4,4,1,0,'2019-08-13 07:09:11.465963','2019-08-13 07:09:11.465994','前端開發'),(5,11,1,0,'2019-08-13 07:08:47.100074','2019-08-13 07:44:05.903782','php編程'),(6,0,1,0,'2019-08-13 07:08:51.451093','2019-08-13 07:43:54.558940','C/C++'),(7,3,1,0,'2019-08-13 07:08:57.390196','2019-08-13 07:08:57.390226','java web'),(8,4,1,0,'2019-08-13 07:09:11.465963','2019-08-13 07:09:11.465994','UI設計'),(9,11,1,0,'2019-08-13 07:09:11.465963','2019-08-13 07:09:11.465994','語文'),(10,145,2,0,'2019-08-13 07:09:11.465963','2019-08-13 07:09:11.465994','數學'),(11,1,2,0,'2019-08-13 07:09:11.465963','2019-08-13 07:09:11.465994','英語');

2.為課程分類添加後端介面的路由,並編寫視圖函數和序列化器

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path(r'categorys/', views.CategoryView.as_view(),),

]

views.py

from . import models
# Create your views here.
from rest_framework.generics import ListAPIView
from .serializers import CourseCategoryModelSerializer, CourseModelsSerializer


class CategoryView(ListAPIView):

    queryset = models.CourseCategory.objects.filter(is_deleted=False,is_show=True)
    serializer_class = CourseCategoryModelSerializer

serializers.py

from rest_framework import serializers
from . import models
class CourseCategoryModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = models.CourseCategory
        fields = ['id', 'name']

lyapi/urls.py

urlpatterns = [
    ......
    path(r'course/',include('course.urls')),

]

訪問後端介面 /course/categorys 可查到分類數據

4.前端發送請求-獲取課程分類資訊

course.vue

<!-- html -->
 <ul class="cate-list">
          <li class="title">課程分類:</li>
          <!-- 點擊不同分類進行高亮效果的切換 --> 
          <li :class="{this:category===0}" @click="category=0">全部</li>
          <li v-for="(value, index) in category_list" :key="value.id" @click="category=value.id" :class="{this:category===value.id}">{{value.name}}</li>   
        </ul>
// js
<script>
    
  import Vheader from "./common/Vheader"
  import Footer from "./common/Footer"
  export default {
      name: "Course",
      data(){
        return{
          category:0,  //默認分類zhi
          category_list:[],
        }
      },
      components:{
        Vheader,
        Footer,
      },

      created() {
        this.$axios.get(`${this.$settings.Host}/course/categorys/`)
        .then((res)=>{
          console.log(res.data);
          this.category_list = res.data;
        })
      }


  }
</script>

此時在前端就可以看到課程分類的效果了

5.後端實現課程列表資訊的介面

urls.py

from django.urls import path
from . import views

urlpatterns = [
    ......
    path(r'courses/', views.CourseView.as_view(),),

]

views.py

from .serializers import CourseModelSerializer
class CourseListAPIView(ListAPIView):
    queryset = Course.objects.filter(is_delete=False, is_show=True).order_by("orders")
    serializer_class = CourseModelSerializer

添加一些測試數據

INSERT INTO `ly_teacher` (`id`,`orders`,`is_show`,`is_deleted`,`created_time`,`updated_time`,`name`,`role`,`title`,`signature`,`image`,`brief`)
VALUES 
(1,1,1,0,'2019-08-13 07:13:01.531992','2019-08-13 07:13:01.532043','李老師',0,'xx公司技術總監','洪七公','teacher/logo2x.png','222');

INSERT INTO `ly_course`
(`id`,`orders`,`is_show`,`is_deleted`,`created_time`,`updated_time`,`name`,`course_img`,`course_type`,`brief`,`level`,`pub_date`,`period`,`attachment_path`,`status`,`students`,`lessons`,`pub_lessons`,`price`,`course_category_id`,`teacher_id`)
VALUES
(1,1,1,0,'2019-08-13 07:13:50.678948','2019-08-15 04:07:11.386224','flask框架','course/Loginbg.3377d0c.jpg',0,'<p>xxxx</p>',1,'2019-08-13',7,'README.md',0,99,110,110,1110.00,1,1),
(2,2,1,0,'2019-08-13 07:15:32.490163','2019-08-15 04:13:22.430368','蘑菇街APP','course/course-cover.jpeg',0,'<p>dxxx</p>',2,'2019-08-13',7,'logo.svg',0,10,50,40,666.00,1,1),
(3,3,1,0,'2019-08-13 07:15:32.490163','2019-08-20 10:49:41.880490','django框架','course/2.jpeg',0,'<p>dxxx</p>',1,'2019-08-13',7,'logo.svg',0,10,50,40,330.00,1,1),
(15,4,1,0,'2019-08-13 07:15:32.490163','2019-08-13 07:15:32.490191','python入門','course/2.jpeg',0,'dxxx',2,'2019-08-13',7,'logo.svg',0,10,50,40,411.00,1,1),
(16,5,1,0,'2019-08-13 07:15:32.490163','2019-08-14 02:28:04.791112','hbase入門','course/2.jpeg',0,'dxxx',1,'2019-08-13',7,'logo.svg',0,10,50,40,400.00,7,1),
(17,6,1,0,'2019-08-13 07:15:32.490163','2019-08-13 07:15:32.490191','路飛學城項目實戰','course/2.jpeg',0,'dxxx',2,'2019-08-13',7,'logo.svg',0,10,50,40,899.00,1,1),
(18,7,1,0,'2019-08-13 07:15:32.490163','2019-08-14 02:29:47.667133','負載均衡','course/2.jpeg',0,'dxxx',2,'2019-08-13',7,'logo.svg',0,10,50,40,1088.00,6,1),
(19,8,1,0,'2019-08-13 07:15:32.490163','2019-08-13 07:15:32.490191','MVC','course/2.jpeg',0,'dxxx',2,'2019-08-13',7,'logo.svg',0,10,50,40,1500.00,1,1),
(20,9,1,0,'2019-08-13 07:15:32.490163','2019-08-14 02:28:52.126968','21天java入門','course/2.jpeg',0,'dxxx',0,'2019-08-13',7,'logo.svg',0,10,50,40,3000.00,7,1),
(21,10,1,0,'2019-08-13 07:15:32.490163','2019-08-14 02:27:01.850049','7天玩轉Linux運維','course/2.jpeg',0,'dxxx',2,'2019-08-13',7,'logo.svg',0,10,50,40,400.00,3,1),
(22,11,1,0,'2019-08-13 07:15:32.490163','2019-08-13 07:15:32.490191','15天掌握flask框架','course/2.jpeg',0,'dxxx',2,'2019-08-13',7,'logo.svg',0,10,50,40,400.00,1,1),
(23,12,1,0,'2019-08-13 07:15:32.490163','2019-08-13 07:23:56.015167','C編程嵌入式','course/2.jpeg',0,'dxxx',1,'2019-08-13',7,'logo.svg',0,10,50,40,399.00,3,1),
(24,13,1,0,'2019-08-13 07:15:32.490163','2019-08-14 02:29:17.872840','3天玩轉樹莓派','course/2.jpeg',0,'dxxx',2,'2019-08-13',7,'logo.svg',0,10,50,40,400.00,3,1),
(25,14,1,0,'2019-08-13 07:15:32.490163','2019-08-14 02:28:30.783768','MongoDB','course/2.jpeg',0,'dxxx',0,'2019-08-13',7,'logo.svg',0,10,50,40,400.00,3,1),
(26,15,1,0,'2019-08-13 07:15:32.490163','2019-08-14 02:30:09.348192','Beego框架入門','course/2.jpeg',0,'dxxx',1,'2019-08-13',7,'logo.svg',0,10,50,40,699.00,2,1),
(27,16,1,0,'2019-08-13 07:15:32.490163','2019-08-15 02:35:20.997672','beego框架進階','course/2.jpeg',0,'<p>dxxx</p>',1,'2019-08-13',7,'logo.svg',0,10,50,50,400.00,2,1),
(28,17,1,0,'2019-08-13 07:15:32.490163','2019-08-13 07:23:44.546598','以太坊入門','course/2.jpeg',0,'dxxx',2,'2019-08-13',7,'logo.svg',0,10,50,40,899.00,2,1),
(29,18,1,0,'2019-08-13 07:15:32.490163','2019-08-15 04:05:10.421736','負載均衡','course/2.jpeg',0,'<div style=\"background:#eeeeee; border:1px solid #cccccc; padding:5px 10px\"><span style=\"color:#16a085\"><span style=\"font-family:Arial,Helvetica,sans-serif\"><span style=\"font-size:28px\"><span style=\"background-color:#f39c12\">dxxx</span></span></span></span><img alt=\"\" src=\"/media/2019/08/15/course-cover.jpeg\" /></div>\r\n\r\n<div style=\"background:#eeeeee; border:1px solid #cccccc; padding:5px 10px\">&nbsp;</div>\r\n\r\n<div style=\"background:#eeeeee; border:1px solid #cccccc; padding:5px 10px\">\r\n<table border=\"1\" cellpadding=\"1\" cellspacing=\"1\" style=\"width:500px\">\r\n    <tbody>\r\n        <tr>\r\n            <td>12321</td>\r\n            <td>3232</td>\r\n            <td>111</td>\r\n        </tr>\r\n        <tr>\r\n            <td>33</td>\r\n            <td>33</td>\r\n            <td>22</td>\r\n        </tr>\r\n        <tr>\r\n            <td>11</td>\r\n            <td>22</td>\r\n            <td>23</td>\r\n        </tr>\r\n    </tbody>\r\n</table>\r\n\r\n<p>&nbsp;</p>\r\n</div>',0,'2019-08-13',7,'logo.svg',0,10,50,40,400.00,3,1);

serializers.py

from rest_framework import serializers
from . import models


class CourseCategoryModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = models.CourseCategory
        fields = ['id', 'name']


class TeacherModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Teacher
        fields = ['name', 'role','title','signature']


class CourseModelsSerializer(serializers.ModelSerializer):
    # teacher_name = serializers.CharField(source='teacher.name')  #自定義欄位,通過sourse關鍵字就能獲取外鍵關聯的指定欄位數據,別忘了在fields裡面指定一下
    # 方式2
    # 序列化器嵌套
    teacher = TeacherModelSerializer()  #將外鍵關聯的屬性指定為關聯表的序列化器對象,就能拿到關聯表序列化出來的所有數據,還需要在fields中指定一下,注意,名稱必須和外鍵屬性名稱相同


    class Meta:
        model = models.Course
        # fields = ["id","name","course_img","students","lessons","pub_lessons","price","teacher",'teacher_name']  #teacher外鍵屬性默認拿的是id值
        fields = ["id","name","course_img","students","lessons","pub_lessons","price","teacher","get_lessons"]  #teacher外鍵屬性默認拿的是id值

如何通過課程找到課時

models.py

class Course(BaseModel):
    
    ......
    class Meta:
        db_table = "ly_course"
        verbose_name = "專題課程"
        verbose_name_plural = "專題課程"

    def __str__(self):
        return "%s" % self.name

    def lesson_list(self):
        """獲取當前課程的前8個課時展示到列表中"""

        # 獲取所有章節
        chapters_list = self.coursechapters.filter(is_delete=False,is_show=True)
        lesson_list = [] # 課時列表
        if chapters_list: 
            for chapter in chapters_list:
                lessons = chapter.coursesections.filter(is_delete=False,is_show=True)[:4]
                if lessons:
                    for lesson in lessons:
                        lesson_list.append({
                            "id":lesson.id,
                            "name":lesson.name,
                            "free_trail":lesson.free_trail
                        })

        return lesson_list[:4]

序列化器欄位增加自定義的模型欄位

class CourseModelSerializer(serializers.ModelSerializer):
# 默認情況,序列化器轉換模型數據時,默認會把外鍵直接轉成主鍵ID值 # 所以我們需要重新設置在序列化器中針對外鍵的序列化 # 這種操作就是一個序列器裡面調用另一個序列化器了.叫"序列化器嵌套"

teacher = TeacherModelSerializer() # coursechapters = CourseChapterModelSerializer(many=True) class Meta: model = Course fields = ("id","name","course_img","students","lessons","pub_lessons","price","teacher","lesson_list")

6.前端顯示列表課程資訊

<!-- html -->  
<div class="course-list">
        <div class="course-item" v-for="(course, courseindex) in course_list">
          <div class="course-image">

            <img :src="course.course_img" alt="">

          </div>
          <div class="course-info">
            <h3><router-link to="">{{course.name}}</router-link> <span><img src="/static/img/avatar1.svg" alt="">{{course.students}}人已加入學習</span></h3>
            <p class="teather-info">{{course.teacher.name}} {{course.teacher.signature}} {{course.teacher.title}} <span>共{{course.lessons}}
              課時/{{course.lessons===course.pub_lessons? '更新完成':`已更新${course.pub_lessons}課時`}}</span></p>
            <ul class="lesson-list">
              <li v-for="(lesson, lessonindex) in course.get_lessons" :key="lessonindex"><span class="lesson-title">0{{lessonindex+1}} | 第{{lesson.lesson}}節:{{lesson.name}}</span><span v-show="lesson.free_trail" class="free">免費</span></li>

            </ul>
            <div class="pay-box">
              <span class="discount-type">限時免費</span>
              <span class="discount-price">¥0.00元</span>
              <span class="original-price">原價:{{course.price}}元</span>
              <span class="buy-now">立即購買</span>
            </div>
          </div>
        </div>
// js
<script>
  export default {
      name: "Course",
      data(){
        return{
          course_list:[],
        }
      },
      created() {
        this.get_course();
      },
      methods:{
          
        // 獲取課程列表數據
        get_course(){
          this.$axios.get(`${this.$settings.Host}/course/courses/`,{
            params:this.fitlers,
          })
          .then((res)=>{
            this.total = res.data.count
            this.course_list = res.data.results;
          })
        }
      }

  }
</script>

7.按照指定分類顯示課程資訊

1.安裝欄位過濾排序

pip install django-filter

2.在settings/dev.py配置文件中增加過濾後端的設置

INSTALLED_APPS = [
    ...
    'django_filters',  # 需要註冊應用,
]

3.在視圖中設置允許過濾的欄位名和引入過濾欄位核心類

from .serializers import CourseModelSerializer
from django_filters.rest_framework import DjangoFilterBackend
class CourseAPIView(ListAPIView):
    queryset = Course.objects.filter(is_delete=False, is_show=True).order_by("orders")
    serializer_class = CourseModelSerializer
    filter_backends = [DjangoFilterBackend, ]
    filter_fields = ('course_category',)

drf測試介面:course/courses/?course_category=1

可以看到分類為1的所有課程資訊

4.前端顯示

<script>
  import Vheader from "./common/Vheader"
  import Footer from "./common/Footer"
  export default {
      name: "Course",
      data(){
        return{
          category:0,  //默認分類值為0 全部
          category_list:[],
          course_list:[],
          fitlers:{},
          total:0
        }
      },
      components:{
        Vheader,
        Footer,
      },

      created() {
        this.get_categorys();
        this.get_course();

      },
      watch:{

        category(){
          if (this.category>0){
            this.fitlers['course_category'] = this.category;
          }else {
            this.fitlers={}
          }

          //console.log('>>>>>',this.fitlers)
          this.get_course(); // 當分類數據發生變化時,觸發獲取數據的動作
        }
      },
        // 獲取所有分類數據
        get_categorys(){
          this.$axios.get(`${this.$settings.Host}/course/categorys/`)
        .then((res)=>{
          //console.log(res.data);
          this.category_list = res.data;
        })
        },

        // 獲取課程列表數據
        get_course(){
          this.$axios.get(`${this.$settings.Host}/course/courses/`,{
            params:this.fitlers,
          })
          .then((res)=>{
            //console.log(res.data);
            this.total = res.data.count
            this.course_list = res.data.results;
          })
        }
      }


  }
</script>

8.分頁顯示課程資訊

1.前端

<template>
     .....
      <!-- 分頁效果展示 -->
      <el-pagination
        background
        :page-size="2"
        layout="prev, pager, next, sizes,jumper"
        :page-sizes="[2, 5,  10, 15, 20]"
        @current-change="handleCurrentChange"
        @size-change="handleSizeChange"
        :total="total">
      </el-pagination>

    </div>
    <Footer></Footer>
  </div>
</template>

<script>
  import Vheader from "./common/Vheader"
  import Footer from "./common/Footer"
  export default {
      name: "Course",
      data(){
       
        }
      },
      components:{
       
      },

      created() {
     
      },
          
      },
      methods:{
        handleSizeChange(val){
          this.fitlers['size'] = val
          // console.log(val);
          this.get_course();
        },
        handleCurrentChange(val){
          this.fitlers['page'] = val
          // console.log(val);
          this.get_course();
        },

        // 獲取所有分類數據
        get_categorys(){
        
        })
        },

        // 獲取課程列表數據
        get_course(){
            
          })
        }
      }


  }
</script>

2.後端

pagenation.py

from rest_framework.pagination import PageNumberPagination
class StandardPageNumberPagination(PageNumberPagination):
    # 默認每一頁顯示的數據量
    page_size = 2
    # 允許客戶端通過get參數來控制每一頁的數據量
    page_size_query_param = "size"
    max_page_size = 10  #客戶端通過size指定獲取數據的條數時,最大不能超過多少

views.py

from django.shortcuts import render


from .pagenations import StandardPageNumberPagination

# 加過濾
class CourseView(ListAPIView):
    ......
    pagination_class = StandardPageNumberPagination 

drf介面調試

course/courses/?page=1

course/courses/?page=1&size=5