路费项目

课程和课程详细
views.py
1.序列化类
from rest_framework import serializers ##############序列化类 class CourseSerializers(serializers.ModelSerializer): class Meta: model=Course # fields=['pk','name','course_img','sub_category'] fields='__all__' # 序列化课程详细的类 class CourseDetailSerializers(serializers.ModelSerializer): #价格策略查询,因为涉及到跨表查询,需要单独拎出来 price_policy_dict = serializers.SerializerMethodField() #课程详细时间,也涉及到跨表 coursedetail__hours = serializers.SerializerMethodField() teachers = serializers.SerializerMethodField() coursechapters = serializers.SerializerMethodField() questions = serializers.SerializerMethodField() courseoutline = serializers.SerializerMethodField() recommend_courses = serializers.SerializerMethodField() class Meta: model=Course fields=['pk','name','course_img','price_policy_dict','coursedetail__hours','teachers','coursechapters','questions','courseoutline','recommend_courses'] # 价格策略,返回的是一个列表,里边是相关信息 #obj代表的是当前的被查询的对象 def get_price_policy_dict(self,obj): temp = [] d = 1 for i in obj.price_policy.all(): # temp.append({i.valid_period,i.price}) temp.append({d:{"valid":i.valid_period,'price':i.price,"price_id":i.pk}}) d+=1 return temp def get_coursedetail__hours(self,obj): return obj.coursedetail.hours def get_teachers(self,obj): temp=[] for item in obj.coursedetail.teachers.all(): temp.append({'name':item.name,"image":item.image}) return temp def get_coursechapters(self, obj): temp = [] for item in obj.course_chapters.all(): temp.append({item.chapter, item.name,item.summary}) return temp def get_questions(self, obj): temp = [] for item in obj.questions.all(): temp.append({item.question, item.answer}) return temp def get_courseoutline(self, obj): temp = [] itemlist=obj.coursedetail.courseoutline_set.all().order_by('-order') for item in itemlist: temp.append({item.title, item.content}) return temp def get_recommend_courses(self, obj): temp = [] for item in obj.coursedetail.recommend_courses.all(): temp.append({item.name,}) return temp
2.视图类
#课程详细页 class Course_s2(APIView): # authentication_classes = [MyAuthentination,] renderer_classes = [JSONRenderer,] def get(self,request,pk=None): #先判断要查询的课程是否带有pk值 #如果不带有PK的话,则表示是查询课程,显示课程列表的 if not pk: #实例化回复信息对象 ret=BaseResponse() try: #自定制分页器,实例化分页器对象 png=Pnpagenation() queryset = Course.objects.all().only('name','course_img','brief',).order_by('-id') # queryset = Course.objects.all().values('name','course_img','brief',) #对数据进行分页, queryset=png.paginate_queryset(queryset=queryset,request=request,view=self) #通过使用自定义的序列化类,对数据进行序列化, res=CourseSerializers(queryset,many=True) # print(res.data,type(res.data)) # ret.data=res.data #取出序列化的结果 res.data方法取出序列化结果 except ObjectDoesNotExist as e: ret.code=2000 ret.error='数据不存在' except Exception as e: ret.code=3000 ret.error='查询失败' # 将ret中的数据返回给前端,ret中包含状态码,数据信息,错误信息 # 因为Response有能够将字典类型的数据处理的能力,所以直接将 # 字典返回{'code': 1000, 'data': res.data, 'error': None} return Response(ret.dict) else: #当含有pk时,表示此时查询的是课程的详细信息,具体到哪一门课程了 print('进来了') ret = BaseResponse() try: queryset= Course.objects.filter(pk=pk).only('name','course_img','coursedetail__hours','coursedetail__video_brief_link').order_by('-id') print(queryset,'到这里了') res=CourseDetailSerializers(queryset,many=True) print(res.data,type(res.data)) ret.data=res.data return Response(ret.dict) except ObjectDoesNotExist as e: ret.code=2000 ret.error='数据不存在' except Exception as e: ret.code=3000 ret.error='查询失败' return Response(ret.dict)

代码
跨域的
#encoding=utf-8 from django.utils.deprecation import MiddlewareMixin class Kuayu(MiddlewareMixin): def process_request(self, request): pass def process_response(self, request, response): if request.method=='OPTIONS': response["Access-Control-Allow-Origin"] = 'http://localhost:8080' response["Access-Control-Allow-Methods"] = 'PUT' response["Access-Control-Allow-Credentials"] = 'True' return response else: response["Access-Control-Allow-Origin"]='http://localhost:8080' return response
BaseResponse.py
#encoding=utf-8 #创建一个类,用于对返回数据的封装,将数据封装成字典,当使用.dict调用的时候 # 就可以返回字典形式的数据 class BaseResponse(object): def __init__(self,code=1000,data=None,error=None): self.code=code self.data=data self.error=error @property def dict(self): ''' @property这样设置,在调用他的实例化对象的情境中 通过对象名.dict就可以得到{'code': 1000, 'data': None, 'error': None} 这种类型的数据 :return: ''' return self.__dict__
Pnpagenation.py 处理分页功能
#encoding=utf-8 #自定制的分页功能 from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination class Pnpagenation(PageNumberPagination): page_size = 4 max_page_size = 10 page_query_param = 'page' page_size_query_param = 'size'

数据库表代码
from django.db import models from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from django.contrib.contenttypes.models import ContentType import hashlib import datetime # ############ 1. 课程相关 ############# class CourseCategory(models.Model): """课程大类, e.g 前端 后端...""" name = models.CharField(max_length=64, unique=True) def __str__(self): return self.name class Meta: verbose_name = "课程大类" verbose_name_plural = "课程大类" class CourseSubCategory(models.Model): """课程子类课程子类, e.g python linux """ category = models.ForeignKey("CourseCategory") name = models.CharField(max_length=64, unique=True) def __str__(self): return self.name class Meta: verbose_name = "课程子类" verbose_name_plural = "课程子类" class DegreeCourse(models.Model): """学位课程""" name = models.CharField(max_length=128, unique=True) course_img = models.CharField(max_length=255, verbose_name="缩略图") brief = models.TextField(verbose_name="学位课程简介", ) total_scholarship = models.PositiveIntegerField(verbose_name="总奖学金(贝里)", default=40000) mentor_compensation_bonus = models.PositiveIntegerField(verbose_name="本课程的导师辅导费用(贝里)", default=15000) period = models.PositiveIntegerField(verbose_name="建议学习周期(days)", default=150, help_text='为了计算学位奖学金') prerequisite = models.TextField(verbose_name="课程先修要求", max_length=1024) teachers = models.ManyToManyField("Teacher", verbose_name="课程讲师") # 用于GenericForeignKey反向查询, 不会生成表字段,切勿删除 # coupon = GenericRelation("Coupon") # 用于GenericForeignKey反向查询,不会生成表字段,切勿删除 degreecourse_price_policy = GenericRelation("PricePolicy") def __str__(self): return self.name class Meta: verbose_name = "学位课程" verbose_name_plural = "学位课程" class Teacher(models.Model): """讲师、导师表""" name = models.CharField(max_length=32, verbose_name='姓名') role_choices = ((1, '讲师'), (2, '导师')) role = models.SmallIntegerField(choices=role_choices, default=1) title = models.CharField(max_length=64, verbose_name="职位、职称") signature = models.CharField(max_length=255, verbose_name="导师签名", blank=True, null=True) image = models.CharField(max_length=128, verbose_name='头像') brief = models.TextField(max_length=1024, verbose_name='简介') def __str__(self): return self.name class Meta: verbose_name = "讲师、导师表" verbose_name_plural = "讲师、导师表" class Scholarship(models.Model): """学位课程奖学金,例如:使用20%的时间学完课程,则奖励5000;使用50%的时间学完课程,则奖励2000""" degree_course = models.ForeignKey("DegreeCourse") time_percent = models.PositiveSmallIntegerField(verbose_name="奖励档位(时间百分比)", help_text="只填百分值,如80,代表80%") value = models.PositiveIntegerField(verbose_name="奖学金数额") def __str__(self): return self.degree_course.name class Meta: verbose_name = "奖学金" verbose_name_plural = "奖学金" class Course(models.Model): """普通课程或学位课的模块""" name = models.CharField(max_length=128, unique=True, verbose_name='课程名称或学位课模块名称') course_img = models.CharField(max_length=255, verbose_name='课程图片') sub_category = models.ForeignKey("CourseSubCategory", verbose_name='课程所属类') course_type_choices = ((1, '付费'), (2, 'VIP专享'), (3, '学位课程')) course_type = models.SmallIntegerField(choices=course_type_choices) # 和学位课做FK,可以为 blank=True, null=True, degree_course = models.ForeignKey("DegreeCourse", blank=True, null=True, help_text="若是学位课程的模块,此处关联学位表") brief = models.TextField(verbose_name="课程概述", max_length=2048) level_choices = ((1, '初级'), (2, '中级'), (3, '高级')) level = models.SmallIntegerField(choices=level_choices, default=1) pub_date = models.DateField(verbose_name="发布日期", blank=True, null=True) period = models.PositiveIntegerField(verbose_name="建议学习周期(days)", default=7) order = models.IntegerField("课程顺序", help_text="从上一个课程数字往后排") attachment_path = models.CharField(max_length=128, verbose_name="课件路径", blank=True, null=True) status_choices = ((1, '上线'), (2, '下线'), (3, '预上线')) status = models.SmallIntegerField(choices=status_choices, default=1) # 用于GenericForeignKey反向查询,不会生成表字段,切勿删除 # coupon = GenericRelation("Coupon") # 用于GenericForeignKey反向查询,不会生成表字段,切勿删除 price_policy = GenericRelation("PricePolicy") # 用于GenericForeignKey反向查询,不会生成表字段,切勿删除 questions = GenericRelation("OftenAskedQuestion") def __str__(self): return self.name class Meta: verbose_name = "课程" verbose_name_plural = "课程" def save(self, *args, **kwargs): if self.course_type == 3: if not self.degree_course: raise ValueError("学位课程必须关联对应的学位表") super(Course, self).save(*args, **kwargs) class CourseDetail(models.Model): """课程详情页内容""" course = models.OneToOneField("Course") hours = models.IntegerField("课时") course_slogan = models.CharField(max_length=125, blank=True, null=True, verbose_name='课程Slogan') video_brief_link = models.CharField(verbose_name='课程介绍', max_length=255, blank=True, null=True) why_study = models.TextField(verbose_name="为什么学习这门课程") what_to_study_brief = models.TextField(verbose_name="我将学到哪些内容") career_improvement = models.TextField(verbose_name="此项目如何有助于我的职业生涯") prerequisite = models.TextField(verbose_name="课程先修要求", max_length=1024) teachers = models.ManyToManyField("Teacher", verbose_name="课程讲师") recommend_courses = models.ManyToManyField('Course', verbose_name="推荐课程", related_name="recommend_by") class Meta: verbose_name = "课程详情" verbose_name_plural = "课程详情" def __str__(self): return self.course.name class OftenAskedQuestion(models.Model): """课程和学位课的常见问题""" content_type = models.ForeignKey(ContentType, verbose_name='关联课程或学位课程表') object_id = models.PositiveIntegerField(verbose_name='关联课程或学位课程表中的课程ID') content_object = GenericForeignKey('content_type', 'object_id') question = models.CharField(max_length=255, verbose_name='问题') answer = models.TextField(max_length=1024, verbose_name='回答') class Meta: unique_together = ('content_type', 'object_id', 'question') verbose_name = "课程和学位课的常见问题" verbose_name_plural = "课程和学位课的常见问题" class CourseOutline(models.Model): """课程大纲""" course_detail = models.ForeignKey("CourseDetail") title = models.CharField(max_length=128, verbose_name='大纲标题') content = models.TextField(max_length=1024, verbose_name='大纲内容') order = models.PositiveSmallIntegerField(default=1, verbose_name='大纲显示顺序') class Meta: unique_together = ('course_detail', 'title') verbose_name = "课程大纲" verbose_name_plural = "课程大纲" class CourseChapter(models.Model): """课程章节""" course = models.ForeignKey("Course", related_name='course_chapters') chapter = models.SmallIntegerField(verbose_name="章节序号(第N章)", 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) def __str__(self): return self.course.name class Meta: unique_together = ("course", 'chapter') verbose_name = "课程章节" verbose_name_plural = "课程章节" class CourseSection(models.Model): """课时""" chapter = models.ForeignKey("CourseChapter", related_name='course_sections') name = models.CharField(max_length=128, verbose_name='课程名称') section_type_choices = ((1, '文档'), (2, '练习'), (3, '视频')) section_type = models.SmallIntegerField(default=3, choices=section_type_choices, verbose_name='课程类型') order = models.PositiveSmallIntegerField(verbose_name="课时顺序", help_text="建议每个课时之间空1至2个值,以备后续插入课时") section_link = models.CharField(verbose_name='课时链接', max_length=255, blank=True, null=True, help_text="若是video,填CC视频的唯一标识(如:ECC9954677D8E1079C33DC5901307461),若是文档或练习,填链接") video_time = 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("是否可试看", default=False) class Meta: unique_together = ('chapter', 'section_link') verbose_name = "课时" verbose_name_plural = "课时" class Homework(models.Model): """课程章节作业和考核""" chapter = models.ForeignKey("CourseChapter") title = models.CharField(max_length=128, verbose_name="作业题目") order = models.PositiveSmallIntegerField("作业顺序", help_text="同一课程的每个作业之前的order值间隔1-2个数") homework_type_choices = ((1, '作业'), (2, '模块通关考核')) homework_type = models.SmallIntegerField(choices=homework_type_choices, default=1) requirement = models.TextField(max_length=1024, verbose_name="作业需求") threshold = models.TextField(max_length=1024, verbose_name="踩分点") recommend_period = models.PositiveSmallIntegerField("推荐完成周期(天)", default=7, help_text='用于计算奖学金') scholarship_value = models.PositiveSmallIntegerField("为该作业分配的奖学金(贝里)") enabled = models.BooleanField(default=True, help_text="本作业如果后期不需要了,不想让学员看到,可以设置为False") note = models.TextField(blank=True, null=True, verbose_name='注意事项') class Meta: unique_together = ("chapter", "title") verbose_name = "课程章节作业和考核" verbose_name_plural = "课程章节作业和考核" class PricePolicy(models.Model): """价格与有课程效期表""" content_type = models.ForeignKey(ContentType, verbose_name='关联普通课或者学位课表',related_name='x2') object_id = models.PositiveIntegerField(verbose_name='关联普通课或者学位课中的课程ID') content_object = GenericForeignKey('content_type', 'object_id') valid_period_choices = ( (1, '1天'), (3, '3天'), (7, '1周'), (14, '2周'), (30, '1个月'), (60, '2个月'), (90, '3个月'), (180, '6个月'), (210, '12个月'), (540, '18个月'), (720, '24个月'), ) valid_period = models.SmallIntegerField(choices=valid_period_choices, verbose_name='课程周期') price = models.FloatField(verbose_name='价格') class Meta: unique_together = ("content_type", 'object_id', "valid_period") verbose_name = "价格与有课程效期表" verbose_name_plural = "价格与有课程效期表" # ############ 2. 账户相关 ############# class Account(models.Model): """用户账户""" username = models.CharField("用户名", max_length=64, unique=True) email = models.EmailField(verbose_name='邮箱', max_length=255, unique=True, blank=True, null=True) password = models.CharField(verbose_name='密码', max_length=128) class Meta: verbose_name = '账户信息' verbose_name_plural = "账户信息" def __str__(self): return self.username def save(self, *args, **kwargs): if not self.pk: m = hashlib.md5() m.update(self.username.encode(encoding="utf-8")) self.uid = m.hexdigest() super(Account, self).save(*args, **kwargs) class UserAuthToken(models.Model): """ 用户Token表 """ user = models.OneToOneField(to="Account") token = models.CharField(max_length=40, unique=True) created = models.DateTimeField(auto_now_add=True) def save(self, *args, **kwargs): self.token = self.generate_key() self.created = datetime.datetime.utcnow() return super(UserAuthToken, self).save(*args, **kwargs) def generate_key(self): """根据用户名和时间生成唯一标识""" username = self.user.username now = str(datetime.datetime.now()).encode('utf-8') md5 = hashlib.md5(username.encode('utf-8')) md5.update(now) return md5.hexdigest() class Meta: verbose_name = '用户Token表' verbose_name_plural = "用户Token表" # class Province(models.Model): # """ # 省份表 # """ # code = models.IntegerField(verbose_name="省代码", unique=True) # name = models.CharField(max_length=64, verbose_name="省名称", unique=True) # # # class City(models.Model): # """ # 城市表 # """ # code = models.IntegerField(verbose_name="市", unique=True) # name = models.CharField(max_length=64, verbose_name="市名称") # province = models.ForeignKey("Province") # class Industry(models.Model): # """ # 行业表 # """ # name = models.CharField(max_length=64, verbose_name="行业名称") # class Profession(models.Model): # """ # 职位表,与行业表外键关联 # """ # name = models.CharField(max_length=64, verbose_name="职位名称") # industry = models.ForeignKey("Industry") class Feedback(models.Model): """用户反馈表""" name = models.CharField(max_length=32, blank=True, null=True) contact = models.CharField(max_length=64, blank=True, null=True) feedback_type_choices = ((1, '网站优化建议'), (2, '烂!我想吐槽'), (3, '网站bug反馈')) feedback_type = models.SmallIntegerField(choices=feedback_type_choices) content = models.TextField(max_length=1024) date = models.DateTimeField(auto_now_add=True) class Meta: verbose_name = '用户反馈表' verbose_name_plural = "用户反馈表" def __str__(self): return self.name class Tags(models.Model): """标签""" tag_type_choices = ((1, '文章标签'), (2, '课程评价标签'), (3, '用户感兴趣技术标签')) tag_type = models.SmallIntegerField(choices=tag_type_choices) name = models.CharField(max_length=64, unique=True, db_index=True) def __str__(self): return self.name # ############ 5. 深科技 ############# class ArticleSource(models.Model): """文章来源""" name = models.CharField(max_length=64, unique=True) class Article(models.Model): """文章资讯""" title = models.CharField(max_length=255, unique=True, db_index=True, verbose_name="文章标题") source = models.ForeignKey("ArticleSource", verbose_name="来源") article_type_choices = ((1, '资讯'), (2, '视频')) article_type = models.SmallIntegerField(choices=article_type_choices, default=1) brief = models.TextField(max_length=512, verbose_name="摘要") head_img = models.CharField(max_length=255, verbose_name='文章图片') content = models.TextField(verbose_name="文章正文") pub_date = models.DateTimeField(verbose_name="上架日期") offline_date = models.DateTimeField(verbose_name="下架日期") status_choices = ((1, '在线'), (2, '下线')) status = models.SmallIntegerField(choices=status_choices, default=1, verbose_name="状态") order = models.SmallIntegerField(default=0, verbose_name="权重", help_text="文章想置顶,可以把数字调大,不要超过1000") vid = models.CharField(max_length=128, verbose_name="视频VID", help_text="文章类型是视频, 则需要添加视频VID", blank=True, null=True) comment_num = models.SmallIntegerField(default=0, verbose_name="评论数") agree_num = models.SmallIntegerField(default=0, verbose_name="点赞数") view_num = models.SmallIntegerField(default=0, verbose_name="观看数") collect_num = models.SmallIntegerField(default=0, verbose_name="收藏数") tags = models.ManyToManyField("Tags", blank=True, verbose_name="标签") date = models.DateTimeField(auto_now_add=True, verbose_name="创建日期") position_choices = ((1, '信息流'), (2, 'banner大图'), (3, 'banner小图')) position = models.SmallIntegerField(choices=position_choices, default=1, verbose_name="位置") comment = GenericRelation("Comment", help_text='用于GenericForeignKey反向查询,不会生成表字段,切勿删除') class Meta: verbose_name = '文章资讯' verbose_name_plural = "文章资讯" def __str__(self): return self.title class Collection(models.Model): """收藏""" account = models.ForeignKey("Account", verbose_name='用户') content_type = models.ForeignKey(ContentType, verbose_name='文章或视频表') object_id = models.PositiveIntegerField(verbose_name='文章或者视频ID') content_object = GenericForeignKey('content_type', 'object_id') date = models.DateTimeField(auto_now_add=True) class Meta: unique_together = ('content_type', 'object_id', 'account') verbose_name = '收藏' verbose_name_plural = "收藏" class Comment(models.Model): """通用的评论表""" account = models.ForeignKey("Account", verbose_name="用户") content_type = models.ForeignKey(ContentType, blank=True, null=True, verbose_name="文章或视频表") object_id = models.PositiveIntegerField(blank=True, null=True, verbose_name='文章或者视频ID') content_object = GenericForeignKey('content_type', 'object_id') p_node = models.ForeignKey("self", blank=True, null=True, verbose_name="父级评论") content = models.TextField(max_length=1024) disagree_number = models.IntegerField(default=0, verbose_name="踩") agree_number = models.IntegerField(default=0, verbose_name="赞同数") date = models.DateTimeField(auto_now_add=True) class Meta: verbose_name = '通用的评论表' verbose_name_plural = "通用的评论表"
admin.py中进行注册表
from django.contrib import admin # Register your models here. from django.contrib.admin import ModelAdmin from .models import * admin.site.register(CourseCategory) admin.site.register(CourseSubCategory) admin.site.register(DegreeCourse) admin.site.register(Teacher) admin.site.register(Scholarship) class CourseConfig(ModelAdmin): list_display = ['pk','name','course_type','degree_course'] admin.site.register(Course,CourseConfig) admin.site.register(CourseDetail) admin.site.register(OftenAskedQuestion) admin.site.register(CourseOutline) admin.site.register(CourseChapter) admin.site.register(CourseSection) admin.site.register(Homework) admin.site.register(PricePolicy) admin.site.register(Account) admin.site.register(UserAuthToken) # admin.site.register(Province) # admin.site.register(City) # admin.site.register(Industry) # admin.site.register(Profession) admin.site.register(Feedback) admin.site.register(Tags) admin.site.register(ArticleSource) admin.site.register(Article) admin.site.register(Collection) admin.site.register(Comment)
https://pan.baidu.com/s/1qsNGrX8M1s2lTAvp1Z2uEQ
浙公网安备 33010602011771号