35 课程模块——所有课程接口(排序,过滤,分页)+单个课程接口(继承RetrieveModelMixin)
课程接口之所有课程接口
class TeacherSerializer(serializers.ModelSerializer): class Meta: model = Teacher fields = ['name', 'role_name', 'title', 'signature', 'image', 'brief'] #由于没有role_name,需要在models中写上获取role_name class CourseSerializer(serializers.ModelSerializer): class Meta: model = Course fields = [ 'id', 'name', 'course_img', 'brief', # 课程介绍 'attachment_path', # 文档链接 'pub_sections', # 发布了多少课时 'price', # 价格 'students', # 学生人数 'period', # 建议学习周期 'sections', # 总课时数量 # choice的字段 'course_type_name', 'level_name', 'status_name', # 原来有这个字段,但是要重写 'teacher', # 小于四个课时,有多少显示多少,多余四个,最多显示4个 'section_list', ] # 重写字段 # 方式一: # teacher=serializers.SerializerMethodField() # def get_teacher(self): # return {} # 方式二:子序列化 teacher = TeacherSerializer()
视图类course/views.py
过滤使用django-filter需要下载 pip install django-filter,记得注册‘django_filter’
from rest_framework.viewsets import GenericViewSet
# from rest_framework.mixins import ListModelMixin
from utils.base_utils import CommonListModelMixin as ListModelMixin
from .serializer import CategorySerializer,CourseSerializer
from django_filters.rest_framework import DjangoFilterBackend
from course import models
from rest_framework.filters import SearchFilter,OrderingFilter
from course.pagenation import CommonPageNumberPagination
# 查询课程详情和查询所有课程接口 class CourseView(GenericViewSet,ListModelMixin): serializer_class = CourseSerializer queryset = models.Course.objects.filter(is_show=True, is_delete=False).order_by('orders') # 过滤 课程分类 # 排序功能:价格,人数,id filter_backends=[OrderingFilter,DjangoFilterBackend] ordering_fields = ['id', 'price', 'students'] filter_fields = ('course_category',) #分页 pagination_class = CommonPageNumberPagination
models.py
# 课程表() 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="付费类型") # 课程介绍(bbs的文章内容) 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) #建议学习周期 period = models.IntegerField(verbose_name="建议学习周期(day)", default=7) # 文档(zip,课程资料) 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="课程状态") # 学习人数 students = models.IntegerField(verbose_name="学习人数", default=0) #总课时数量 sections = models.IntegerField(verbose_name="总课时数量", default=0) # 课时更新数量 pub_sections = models.IntegerField(verbose_name="课时更新数量", default=0) price = models.DecimalField(max_digits=6, decimal_places=2, verbose_name="课程原价", default=0) # 课程分类,跟分类表一对多,关联字段写在多的一方 # db_constraint=False:实际编码中,外键关联是人为约束,不是直接使用关联 # 不建立外键,但是orm使用跟之前一样 # blank=True 后台管理,录入的时候,blank=True可以为空 course_category = models.ForeignKey('CourseCategory', on_delete=models.SET_NULL, db_constraint=False, null=True, blank=True, verbose_name="课程分类") # 一套课程是一个老师讲,一对多 teacher = models.ForeignKey("Teacher", on_delete=models.DO_NOTHING, null=True,db_constraint=False, blank=True, verbose_name="授课老师") #重写字段 @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()
#检索所有章节课时,返回前4课时,不足全部返回 @property def section_list(self): temp_session_list=[] coursechapter_list=self.coursechapters.all() for coursechapter in coursechapter_list:
#取出该章节下所有课时 coursesection_list=coursechapter.coursesections.all() for temp_sesection in coursesection_list: temp_session_list.append({'id':temp_sesection.id,'name':temp_sesection.name,'free_trail':temp_sesection.free_trail}) if len(temp_session_list)>=4: return temp_session_list return temp_session_list
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="导师描述")
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
#分页 course/pagenation.py
from rest_framework.pagination import PageNumberPagination class CommonPageNumberPagination(PageNumberPagination): page_size = 2 page_query_param = 'page' #http://127.0.0.1:8000/book/?page=3 page_size_query_param = 'page_size' # 用size来调整显示每页的条数,即每页显示多少条 max_page_size = 5 # 限制每页最大显示3条
路由urls.py
router.register('course_list', views.CourseView, 'course_list')
查询单个课程详情接口(就用了上面查询所有,只是配置了一个:RetrieveModelMixin)
# 查询所有课程接口和单课程查询(就是加了个RetrieveModelMixin) from utils.base_utils import common_RetrieveModelMixin as RetrieveModelMixin class CourseView(GenericViewSet, ListModelMixin,RetrieveModelMixin): serializer_class = CourseSerializer queryset = Course.objects.filter(is_show=True, is_delete=False).order_by('orders') # 过滤 课程分类 # 排序功能:价格,人数,id filter_backends = [OrderingFilter, DjangoFilterBackend] ordering_fields = ['price', 'students', 'id'] # 按price,student,id排序(用Ordering作为key搜索) filter_fields = ('course_category',) # 按课程分类过滤 # 分页 pagination_class = MyPageNumberPagination # 重写RetrieveModelMixin from rest_framework.mixins import ListModelMixin,RetrieveModelMixin from .response import APIResponse class common_RetrieveModelMixin(RetrieveModelMixin): def retrieve(self, request, *args, **kwargs): res = super().retrieve(request, *args, **kwargs) return APIResponse(data=res.data)