课程模块app应用、三大分页器、过滤组件

一、微信小程序

https://developers.weixin.qq.com/miniprogram/dev/devtools/stable.html

https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html

1、创建course应用app

2、dev中注册course

3、路由

 01、创建子路由

 02、主路由:

path('course/', include('course.urls')),

4、models 表设计

     分析:

  免费课

   

 

 实战课

轻课:

 

课程(免费课、实战课、轻课)与 表 的关系:

1、老师表,可以只有一张表,放在课件 基表中

2、分类表,可以只有一张表,放在课件 基表中

3、章节表,与课程 相对应,所以需要三张章节表,放在课程 子表中

4、课时表,与课程章节 相对应,所以需要三张章节表,放在课程 子表中

5、评论表 (外键自关联)

 

连表字段:

总时长:每个课程的每个章节的每个课时视频时间总和

             (是估值,直接在课程表中写一个固定字段)

总人气:每个课程被学生学习的总量 (学习的人数),连表到user,查看课程与用户的关系记录总数(假值,直接在课程表中写一个固定字段)

总课时:每个课程的每个章节的总课时之和(确切值,直接在课程表中写一个固定字段,创建时算好算入)

数据库优化:大量查询的连表计算字段,可以直接用一个字段表示,能不连表尽量别连表

 

用uuid做主键,多个表之间主键不会重复

impord uuid

uuid.uuid4()

代码:

from django.db import models

from utils.model import BaseModel
class CourseCategory(BaseModel):
    """分类"""
    name = models.CharField(max_length=64, unique=True, verbose_name="分类名称")
    class Meta:
        db_table = "luffy_course_category"
        verbose_name = "分类"
        verbose_name_plural = verbose_name

    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="courses", max_length=255, verbose_name="封面图片", blank=True, null=True)
    course_type = models.SmallIntegerField(choices=course_type, default=0, verbose_name="付费类型")
    brief = models.TextField(max_length=2048, verbose_name="详情介绍", null=True, blank=True)
    level = models.SmallIntegerField(choices=level_choices, default=0, verbose_name="难度等级")
    pub_date = models.DateField(verbose_name="发布日期", auto_now_add=True)
    attachment_path = models.FileField(upload_to="attachment", max_length=128, verbose_name="课件路径", blank=True, null=True)
    status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="课程状态")
    pub_sections = models.IntegerField(verbose_name="课时更新数量", default=0)
    price = models.DecimalField(max_digits=6, decimal_places=2, verbose_name="课程原价", default=0)

    students = models.IntegerField(verbose_name="学习人数", default=0)
    period = models.IntegerField(verbose_name="建议学习周期(day)", default=7)
    sections = models.IntegerField(verbose_name="总课时数量", default=0)

    teacher = models.ForeignKey("Teacher", on_delete=models.DO_NOTHING, null=True, blank=True, verbose_name="授课老师", db_constraint=False)
    course_category = models.ForeignKey("CourseCategory", on_delete=models.SET_NULL, null=True,
                                        blank=True,
                                        verbose_name="课程分类",
                                        db_constraint=False)

    @property
    def course_type_name(self):
        return self.get_course_type_display()

    @property
    def level_name(self):
        return self.get_level_display()

    @property
    def status_name(self):
        return self.get_status_display()


    # 连表序列化字段
    @property
    def section_list(self):
        # 检索所以章节所以课时,返回前4课时,不足4课时全部返回
        temp_section_list = []

        for chapter in self.coursechapters.all():
            for section in chapter.coursesections.all():
                temp_section_list.append({
                    'name': section.name,
                    'section_link': section.section_link,
                    'duration': section.duration,
                    'free_trail': section.free_trail,
                })
                if len(temp_section_list) >= 4:
                    return temp_section_list  # 最多4条

        return temp_section_list  # 不足4条

    class Meta:
        db_table = "luffy_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="导师名")
    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="导师描述")

    @property
    def role_name(self):
        return self.get_role_display()

    class Meta:
        db_table = "luffy_teacher"
        verbose_name = "导师"
        verbose_name_plural = verbose_name

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

class CourseChapter(BaseModel):
    """章节"""
    course = models.ForeignKey("Course", related_name='coursechapters', on_delete=models.CASCADE, verbose_name="课程名称", db_constraint=False)
    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 = "luffy_course_chapter"
        verbose_name = "章节"
        verbose_name_plural = verbose_name

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

class CourseSection(BaseModel):
    """课时"""
    section_type_choices = (
        (0, '文档'),
        (1, '练习'),
        (2, '视频')
    )
    chapter = models.ForeignKey("CourseChapter", related_name='coursesections', on_delete=models.CASCADE,
                                verbose_name="课程章节", db_constraint=False)
    name = models.CharField(max_length=128, verbose_name="课时标题")
    orders = models.PositiveSmallIntegerField(verbose_name="课时排序")
    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)

    class Meta:
        db_table = "luffy_course_Section"
        verbose_name = "课时"
        verbose_name_plural = verbose_name

    def __str__(self):
        # 在断关联情况下,可以先创课时,后创章节,但没有创章节时,查看课时就会报错(admin|xadmin)
        try:
            return "%s-%s" % (self.chapter, self.name)
        except:
            return self.name
models表类

 

5、admin管理 表类

 6、数据库迁移命令:

python manage.py makemigrations

python manage.py migrate

7、navicat填充数据

 

 

8、前端:views中建文件:FreeCourse

9、写路由 router中 的index.js文件

 10 、课程分类:群查接口

 

 

 

 

 11、课程:群查接口

viesw文件

 serializers文件

子序列化字段

 自定义序列化字段

连表 序列化字段

 

urls文件

分页器组件:

 

 paginate_queryset、filter_queryset 从GenericViewSet中的GenericAPIView中来的

点击GenericAPIView有如下:

 

 

 

 

 

from rest_framework.generic import GenericAPIView

GenericAPIView 的五个方法五个属性:

1、queryset

def get_queryset(self):

2、serializer_class

def get_serializer(self, *args, **kwargs):
def get_serializer_class(self):

3、filter_backends   配置过滤类 们

# 调用配置的过滤类完成过滤(都是在群查接口中完成,传入queryset,接收过滤后的queryset)

def filter_queryset(self, queryset):

4、pagination_class   配置分页类

# 调用配置的分页类完成分页(都是在群查接口中完成,传入queryset,接收分页过滤后的分页对象queryset)

def paginate_queryset(self, queryset):

5、

# 从pagination 中导入 基础分页,偏移分页,游标分页

from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination

 

 

1)PageNumberPagination 基础分页器的使用

方法一、

 

 

方法二、

1.在course文件夹中新建pagination文件

 2.views中

 

 2)LimitOffsetPagination      偏移分页器的使用

 

 views文件

 

 

 

 3) LimitOffsetPagination      游标分页器的使用

 

 

 

 

 

 总结

 

 

 过滤组件:

1、搜索过滤

 

 

 views文件

 

 总结:

 

2、排序过滤

 

 

 

 

 

 

 

 

 总结:

 

 

3、自定义过滤组件

在course文件夹中新建filters文件

 

 

views文件

 

 

 

 

 

总结:

 4、课程分类过滤

方法一:

01、项目终端:

pip install django-filter

02、views文件

 

 

 3、总结

 

 方法二、

 

 views文件

 

 总结:

 方法三:区间过滤

 views文件

 

 

posted @ 2020-03-07 20:42  薛定谔的猫66  阅读(391)  评论(0)    收藏  举报