项目:K12(在线学习的平台)

一、背景

目的是做一个在线的学习平台,提高学生的课程完成度

K12:大目标是要取代线下班

  • - 录制专门的视频
  • - 导师的监管:如果没有主动和那个学生聊天,就扣钱
  • - 学生的激励:如果提前学完了,学习能力很强,可以免学费

二、系统架构

  1. - 主站
  2. - rest api
  3. - vue
  4. - 导师后台 (stark)
  5. - django
  6. - stark
  7. - 管理后台 (stark)
  8. - django
  9. - stark

三、人员和部门

  1. - 后端开发(5人)
  2. - 主站(3
  3. - 导师后台(1
  4. - 管理后台(1
  5. - 前端开发(1
  6. - UI 1
  7. - 测试(1
  8. - 运维(部署:上线)(1
  9. - 运营(推广出去)(2
  10. - 销售 2
  11. - 导师 2
  12. - 产品经理 1
  13.  
  14. - 人事
  15. - 财务

四、需求分析

  1. 主站
  2. - 课程
  3. - 普通课程、学位课
  4. - 普通课程:比较小的课程
  5. - 学位课:从开始+项目+就业
  6. - 分配一对一的导师
  7. - 导师对你进行监管,督促你学习
  8. - 保就业
  9. - 如果你%50的时间学完了,退一般的学费,等。
  10. - 课程列表、课程详细
  11. - 课程周期的不同定价格
  12. - 个人的课程中心
  13. - 支付
  14. - 银联- 支付宝
  15. - 微信
  16. - 优惠券策略(满减(满多少减多少),立减,打折)
  17. - 贝里:可直接抵现金
  18. - 个人购物车
  19.  
  20. - 深科技
  21. - 文章或者爬取的别人的文章(运营需要审核)
         - 深刻有哪些功能?
            - 点赞、评论、查看、收藏
  22.  
  23. - 登录 、注册
  24. 导师后台
  25. 管理后台

具体进一步谈业务需求

  1. a、课程:
  2. 业务相关:
  3. 1、学位课,如果你学的快;最多返指定金额的65%
  4. 2、作业做的好,会把额外的35%返给你
  5. 3、普通课程购买课程后,在我的订单中去评价
  6. 4、购物车的数据没有数据表。保存到redis里面去了
  7.  
  8. 两大部分操作
  9. #redis操作
  10. 在课程详细页面,选择价格策略,点击加入购物车,吧视频和价格策略放到了redis
  11. 在购物车页面,
  12. 可以对redis中保存的购买的视频数据和价格数据可以删除,修改,添加,查看(刷新)
  13. 选中,去结算中心
  14. #数据库操作
  15. #pip freeze > requirement.txt #生成文件
  16. #pip install -r requirement.txt #下载所有的版本
  17. 在结算页面:
  18. 优惠券
  19. - 选择单一的优惠券(通用、满减、折扣)
  20. - 课程优惠券:绑定课程的优惠券
  21. - 选择全站的优惠券(通用、满减、折扣)
  22. #单一的优惠券用完,再计算,看是否满足全站的通用卷
  23. - 选择贝里
  24. - 选择支付宝,点击立即支付
  25. - 在数据库中生成一个订单
  26. 这个订单如果用了优惠券,优惠券状态改为已使用
  27. 如果用了贝里,贝里的金额减少
  28. 如果取消订单,优惠券才不是使用状态
  29. 在支付页面,扫码状态为已支付
  30.  
  31. 在我的订单中应该去数据库中读数据
  32. 在购物车或者结算中心的时候去redis里面读数据
  33. 课程列表和课程详细等等等
  34. 如果购买课程
  35. - 普通课程
  36. - 学位课程
  37. - 每个模块生成记录(人和课程模块的记录) - 买完之后自动生成
  38. - 开通模块(后台)
  39. - 导师跟进(导师)
  40. - 交作业(主站)
  41. b、深科技相关
  42. 来源
  43. 文章
  44. 收藏
  45. 通用评论表
  46. c、购买支付流程
  47. 课程id和价格策略id
  48. 传值的时候可以传两个值
  49. - 通过策略id找到买的那个课程
  50. - 通过课程id 获取所有的价格策略
  51. 处理请求
  52. 1、检测课程是否上线,下线
  53. 2、通过课程id 获取所有的价格策略,和传过来的进行对比
  54. 3、检测用户提交的价格策略是否在所有的价格策略中
  55. 4、将购物的视频添加到购物车(redis)
  56. - 同一个课程只能买一个,不允许一下加入两个
  57. 吧数据放到redis中,那么怎么存?
  58. 一个人就有一个购物车。可以通过用户id来存
  59. 所有的购物车= {
  60. 1:{
  61. 课程id1:{'prices':[],'price':9,'title':'python','img':'课程图片'},
  62. 课程id2:{'prices':[]}
  63. }
  64. }
  65. #如果看到课程已经在里面了,就不在里面添加了,这也就是用redis的原因
  66. class ShoppingCat(APIView):
  67. def post():
  68. #点击加入购物车保存数据到redis
  69. def get():
  70. #查看购物车列表
  71. def delete():
  72. #删除
  73. def patch():
  74. #局部更新
  75. pass
  76. 5、去结算(先简单的说一下)
  77. 买的所有的课程
  78. 课程1 价格策略
  79. 课程2 价格策略
  80. 课程3 价格策略
  81. 点击了去结算
  82. 优惠券
  83. 贝里

五、表结构

  1. 课程相关的13张表
      课程大类表:e.g 前端,后端
  2.   课程子类表:e.g python linux
  3.   普通课程表
  4.   学位课表
  5.   ##学位课可以有如下好处
  6.   学位奖学金表
  7.   ##当然学位课和普通课程共有的
  8.   价格策略表
  9.   优惠券表
  10.   课程详细表
  11.   课程章节表
  12.   课程目录表
  13.   课程问答表
  14.   课程评价(先不讨论)
      课程大纲
  15.   ##
  16.   老师表
  17.  
  18.   contenttype
  19.   contentType 可以一下关联两张表,django自己提供了,不用自己创建
  20.  
  21. 深科技相关的4张表
      文章来源
      文章资讯
      收藏(既能收藏课程,也能收藏文章,可以用contenttype
      评论(可以用contenttype的形式也可以用ForeignKey的形式)
  22.  
  23. 用户相关的两张表
      用户信息表account
      用户认证表userauthtoken
        - 如果用户初次登录,给用户创建一个token,如果已经有token了,下次用户访问的时候直接带上token,如果没有token就说明没有登录,就没有访问其他页面的权限
  24.  
  25. 购买支付相关的7张表
      已报名课程表EnrolledCourse(谁购买了那个课程)
      学位课报名表
      已报名的学位课程表EnrolledDegreeCourse
      优惠券发放、消费记录
      订单表
      订单详情
      贝里交易记录
  26.  
  27. 其他相关的6张表
      课程评价
      学位课程评价
      学位课程的模块学习进度
      为学生开通一个模块
      学生作业记录及成绩
      学员跟进记录
      
      
      
      
      
  1.   

1、简单表结构设计分析:

需要知道的知识点:

  现在学位课和普通课程都有自己的价格策略和优惠券,现在是学位课已经有了自己的价格策略,那么如果普通课程也要加价格策略,怎么弄呢?

一下有三种方法:

方法一:再单独创建一个表

方法二:不用单独创建一个表,可以多添加一个字段,其中的一个为NULL。相比方法一省了一张表

方法三:可以通过ContentType ,这个表里面存的是应用的名字以及表名。但是在我们makemigrations和migrate的时候django已经帮我们创建好了,如下图。就不用我们自己创建了

这样关联的好处:可以ForeignKey任何一张表。里面的xid是关联表的某一行数据,

这样关联以后,如果想在价格策略里面在添加一行数据,怎么添加呢?

有两种方式:

方式一:手动插入

  • 自己手动查出content_type_id 和关联表里的某一行数据xid。查出来添加到价格策略表里面去

方式二:利用GenericForeignKey

  • 可以通过导入 GenericForeignKey(GenericForeignKey有自动查找的功能,协助你快速做操作,没有也可以,自己手动查询)
  1. from django.contrib.contenttypes.fields import GenericForeignKey

使用:

  1. content_object = GenericForeignKey('content_type', 'object_id') #一下可以查到两个表的数据,自动插入到价格策略表里了,
    优惠券表也是如此。只是为了查询方便

另外补充一个GenericRelation

  1. from django.contrib.contenttypes.fields import GenericRelation

GenericRelation:也是帮助做快速查询的,就像反向关联的releated_name=‘xx’。以后查找的时候通可以通过点字段名的方式去查找

  1. # 用于GenericForeignKey反向查询, 不会生成表字段,切勿删除
  2. coupon = GenericRelation("Coupon") #也是帮助做快速查询的,可以直接查出所有的学位课的价格策略等

2、具体表结构设计如下:

  1. 1 from django.db import models
  2. 2 from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
  3. 3 #GenericForeignKey有自动查找的功能,协助你快速做操作,没有也可以,自己手动查询
  4. 4 #GenericRelation:也是帮助做快速查询的,可以直接查出所有的学位课的价格策略等
  5. 5
  6. 6 from django.contrib.contenttypes.models import ContentType
  7. 7 from django.db.models import Q
  8. 8 from django.utils.safestring import mark_safe
  9. 9 from django.db import models
  10. 10 import hashlib
  11. 11
  12. 12 class CourseCategory(models.Model):
  13. 13 """课程大类, e.g 前端 后端..."""
  14. 14 name = models.CharField(max_length=64, unique=True)
  15. 15
  16. 16 def __str__(self):
  17. 17 return "%s" % self.name
  18. 18
  19. 19 class Meta:
  20. 20 verbose_name = "课程大类" #单数
  21. 21 verbose_name_plural = "课程大类" #复数
  22. 22
  23. 23 class CourseSubCategory(models.Model):
  24. 24 """课程子类, e.g python linux """
  25. 25 category = models.ForeignKey("CourseCategory",verbose_name='所属类')
  26. 26 name = models.CharField(max_length=64, unique=True)
  27. 27
  28. 28 def __str__(self):
  29. 29 return "%s" % self.name
  30. 30
  31. 31 class Meta:
  32. 32 verbose_name = "课程子类"
  33. 33 verbose_name_plural = "课程子类"
  34. 34
  35. 35 class DegreeCourse(models.Model):
  36. 36 """学位课程"""
  37. 37 name = models.CharField(max_length=128, unique=True)
  38. 38 course_img = models.CharField(max_length=255, verbose_name="缩略图")
  39. 39 brief = models.TextField(verbose_name="学位课程简介", )
  40. 40 total_scholarship = models.PositiveIntegerField(verbose_name="总奖学金(贝里)", default=40000)
  41. 41 mentor_compensation_bonus = models.PositiveIntegerField(verbose_name="本课程的导师辅导费用(贝里)", default=15000)
  42. 42 # 用于GenericForeignKey反向查询, 不会生成表字段,切勿删除
  43. 43 coupon = GenericRelation("Coupon") #也是帮助做快速查询的,可以直接查出所有的学位课的价格策略等
  44. 44 # 为了计算学位奖学金
  45. 45 period = models.PositiveIntegerField(verbose_name="建议学习周期(days)", default=150)
  46. 46 prerequisite = models.TextField(verbose_name="课程先修要求", max_length=1024)
  47. 47 teachers = models.ManyToManyField("Teacher", verbose_name="课程讲师")
  48. 48 # 用于GenericForeignKey反向查询,不会生成表字段,切勿删除
  49. 49 degreecourse_price_policy = GenericRelation("PricePolicy")
  50. 50
  51. 51 def __str__(self):
  52. 52 return self.name
  53. 53
  54. 54 class Course(models.Model):
  55. 55 """课程"""
  56. 56 name = models.CharField(max_length=128, unique=True)
  57. 57 course_img = models.CharField(max_length=255)
  58. 58 sub_category = models.ForeignKey("CourseSubCategory")
  59. 59 course_type_choices = ((0, '付费'), (1, 'VIP专享'), (2, '学位课程'))
  60. 60 course_type = models.SmallIntegerField(choices=course_type_choices)
  61. 61 degree_course = models.ForeignKey("DegreeCourse", blank=True, null=True, help_text="若是学位课程,此处关联学位表")
  62. 62 brief = models.TextField(verbose_name="课程概述", max_length=2048)
  63. 63 level_choices = ((0, '初级'), (1, '中级'), (2, '高级'))
  64. 64 level = models.SmallIntegerField(choices=level_choices, default=1)
  65. 65 pub_date = models.DateField(verbose_name="发布日期", blank=True, null=True)
  66. 66 period = models.PositiveIntegerField(verbose_name="建议学习周期(days)", default=7)
  67. 67 order = models.IntegerField("课程顺序", help_text="从上一个课程数字往后排")
  68. 68 attachment_path = models.CharField(max_length=128, verbose_name="课件路径", blank=True, null=True)
  69. 69 status_choices = ((0, '上线'), (1, '下线'), (2, '预上线'))
  70. 70 status = models.SmallIntegerField(choices=status_choices, default=0)
  71. 71 template_id = models.SmallIntegerField("前端模板id", default=1)
  72. 72 coupon = GenericRelation("Coupon")
  73. 73 # 用于GenericForeignKey反向查询,不会生成表字段,切勿删除
  74. 74 price_policy = GenericRelation("PricePolicy")
  75. 75
  76. 76 def __str__(self):
  77. 77 return "%s(%s)" % (self.name, self.get_course_type_display())
  78. 78
  79. 79 def save(self, *args, **kwargs):
  80. 80 if self.course_type == 2:
  81. 81 if not self.degree_course:
  82. 82 raise ValueError("学位课程必须关联对应的学位表")
  83. 83 super(Course, self).save(*args, **kwargs)
  84. 84
  85. 85 class CourseDetail(models.Model):
  86. 86 """课程详情页内容"""
  87. 87 course = models.OneToOneField("Course")
  88. 88 hours = models.IntegerField("课时")
  89. 89 course_slogan = models.CharField(max_length=125, blank=True, null=True)
  90. 90 video_brief_link = models.CharField(verbose_name='课程介绍', max_length=255, blank=True, null=True)
  91. 91 why_study = models.TextField(verbose_name="为什么学习这门课程")
  92. 92 what_to_study_brief = models.TextField(verbose_name="我将学到哪些内容")
  93. 93 career_improvement = models.TextField(verbose_name="此项目如何有助于我的职业生涯")
  94. 94 prerequisite = models.TextField(verbose_name="课程先修要求", max_length=1024)
  95. 95 recommend_courses = models.ManyToManyField("Course", related_name="recommend_by", blank=True)
  96. 96 teachers = models.ManyToManyField("Teacher", verbose_name="课程讲师")
  97. 97
  98. 98 def __str__(self):
  99. 99 return "%s" % self.course
  100. 100
  101. 101 class OftenAskedQuestion(models.Model):
  102. 102 """常见问题"""
  103. 103 content_type = models.ForeignKey(ContentType,
  104. 104 limit_choices_to={'model__contains': 'course'}) # 关联course or degree_course
  105. 105 object_id = models.PositiveIntegerField()
  106. 106 content_object = GenericForeignKey('content_type', 'object_id')
  107. 107
  108. 108 question = models.CharField(max_length=255)
  109. 109 answer = models.TextField(max_length=1024)
  110. 110
  111. 111 def __str__(self):
  112. 112 return "%s-%s" % (self.content_object, self.question)
  113. 113
  114. 114 class Meta:
  115. 115 unique_together = ('content_type', 'object_id', 'question')
  116. 116
  117. 117 class CourseOutline(models.Model):
  118. 118 """课程大纲"""
  119. 119 course_detail = models.ForeignKey("CourseDetail")
  120. 120 title = models.CharField(max_length=128)
  121. 121 # 前端显示顺序
  122. 122 order = models.PositiveSmallIntegerField(default=1)
  123. 123
  124. 124 content = models.TextField("内容", max_length=2048)
  125. 125
  126. 126 def __str__(self):
  127. 127 return "%s" % self.title
  128. 128
  129. 129 class Meta:
  130. 130 unique_together = ('course_detail', 'title')
  131. 131
  132. 132 class CourseChapter(models.Model):
  133. 133 """课程章节"""
  134. 134 course = models.ForeignKey("Course", related_name='coursechapters')
  135. 135 chapter = models.SmallIntegerField(verbose_name="第几章", default=1)
  136. 136 name = models.CharField(max_length=128)
  137. 137 summary = models.TextField(verbose_name="章节介绍", blank=True, null=True)
  138. 138 pub_date = models.DateField(verbose_name="发布日期", auto_now_add=True)
  139. 139
  140. 140 class Meta:
  141. 141 unique_together = ("course", 'chapter')
  142. 142
  143. 143 def __str__(self):
  144. 144 return "%s:(第%s章)%s" % (self.course, self.chapter, self.name)
  145. 145
  146. 146 class Teacher(models.Model):
  147. 147 """讲师、导师表"""
  148. 148 name = models.CharField(max_length=32)
  149. 149 role_choices = ((0, '讲师'), (1, '导师'))
  150. 150 role = models.SmallIntegerField(choices=role_choices, default=0)
  151. 151 title = models.CharField(max_length=64, verbose_name="职位、职称")
  152. 152 signature = models.CharField(max_length=255, help_text="导师签名", blank=True, null=True)
  153. 153 image = models.CharField(max_length=128)
  154. 154 brief = models.TextField(max_length=1024)
  155. 155
  156. 156 def __str__(self):
  157. 157 return self.name
  158. 158
  159. 159 class PricePolicy(models.Model):
  160. 160 """价格与有课程效期表"""
  161. 161 content_type = models.ForeignKey(ContentType) # 关联course or degree_course
  162. 162 object_id = models.PositiveIntegerField()
  163. 163 content_object = GenericForeignKey('content_type', 'object_id')
  164. 164
  165. 165 # course = models.ForeignKey("Course")
  166. 166 valid_period_choices = ((1, '1天'), (3, '3天'),
  167. 167 (7, '1周'), (14, '2周'),
  168. 168 (30, '1个月'),
  169. 169 (60, '2个月'),
  170. 170 (90, '3个月'),
  171. 171 (180, '6个月'), (210, '12个月'),
  172. 172 (540, '18个月'), (720, '24个月'),
  173. 173 )
  174. 174 valid_period = models.SmallIntegerField(choices=valid_period_choices)
  175. 175 price = models.FloatField()
  176. 176
  177. 177 class Meta:
  178. 178 unique_together = ("content_type", 'object_id', "valid_period")
  179. 179
  180. 180 def __str__(self):
  181. 181 return "%s(%s)%s" % (self.content_object, self.get_valid_period_display(), self.price)
  182. 182
  183. 183 class CourseSection(models.Model):
  184. 184 """课时目录"""
  185. 185 chapter = models.ForeignKey("CourseChapter", related_name='coursesections')
  186. 186 name = models.CharField(max_length=128)
  187. 187 order = models.PositiveSmallIntegerField(verbose_name="课时排序", help_text="建议每个课时之间空1至2个值,以备后续插入课时")
  188. 188 section_type_choices = ((0, '文档'), (1, '练习'), (2, '视频'))
  189. 189 section_type = models.SmallIntegerField(default=2, choices=section_type_choices)
  190. 190
  191. 191
  192. 192 section_link = models.CharField(max_length=255, blank=True, null=True, help_text="若是video,填vid,若是文档,填link")
  193. 193 # vid:cc视频,唯一标识:sdfsgdfgdgfhgfh
  194. 194 video_time = models.CharField(verbose_name="视频时长", blank=True, null=True, max_length=32) # 仅在前端展示使用
  195. 195 pub_date = models.DateTimeField(verbose_name="发布时间", auto_now_add=True)
  196. 196 free_trail = models.BooleanField("是否可试看", default=False)
  197. 197
  198. 198
  199. 199 class Meta:
  200. 200 unique_together = ('chapter', 'section_link')
  201. 201
  202. 202
  203. 203 def __str__(self):
  204. 204 return "%s-%s" % (self.chapter, self.name)
  205. 205
  206. 206 class Coupon(models.Model):
  207. 207 """优惠券生成规则"""
  208. 208 name = models.CharField(max_length=64, verbose_name="活动名称")
  209. 209 brief = models.TextField(blank=True, null=True, verbose_name="优惠券介绍")
  210. 210 coupon_type_choices = ((0, '通用券'), (1, '满减券'), (2, '折扣券'))
  211. 211 coupon_type = models.SmallIntegerField(choices=coupon_type_choices, default=0, verbose_name="券类型")
  212. 212
  213. 213 money_equivalent_value = models.IntegerField(verbose_name="等值货币")
  214. 214 off_percent = models.PositiveSmallIntegerField("折扣百分比", help_text="只针对折扣券,例7.9折,写79", blank=True, null=True)
  215. 215 minimum_consume = models.PositiveIntegerField("最低消费", default=0, help_text="仅在满减券时填写此字段")
  216. 216
  217. 217 content_type = models.ForeignKey(ContentType, blank=True, null=True)
  218. 218 object_id = models.PositiveIntegerField("绑定课程", blank=True, null=True, help_text="可以把优惠券跟课程绑定")
  219. 219 content_object = GenericForeignKey('content_type', 'object_id')
  220. 220
  221. 221 quantity = models.PositiveIntegerField("数量(张)", default=1)
  222. 222 open_date = models.DateField("优惠券领取开始时间")
  223. 223 close_date = models.DateField("优惠券领取结束时间")
  224. 224 valid_begin_date = models.DateField(verbose_name="有效期开始时间", blank=True, null=True)
  225. 225 valid_end_date = models.DateField(verbose_name="有效结束时间", blank=True, null=True)
  226. 226 coupon_valid_days = models.PositiveIntegerField(verbose_name="优惠券有效期(天)", blank=True, null=True,
  227. 227 help_text="自券被领时开始算起")
  228. 228 date = models.DateTimeField(auto_now_add=True)
  229. 229
  230. 230 def __str__(self):
  231. 231 return "%s(%s)" % (self.get_coupon_type_display(), self.name)
  232. 232
  233. 233 def save(self, *args, **kwargs):
  234. 234 if not self.coupon_valid_days or (self.valid_begin_date and self.valid_end_date):
  235. 235 if self.valid_begin_date and self.valid_end_date:
  236. 236 if self.valid_end_date <= self.valid_begin_date:
  237. 237 raise ValueError("valid_end_date 有效期结束日期必须晚于 valid_begin_date ")
  238. 238 if self.coupon_valid_days == 0:
  239. 239 raise ValueError("coupon_valid_days 有效期不能为0")
  240. 240 if self.close_date < self.open_date:
  241. 241 raise ValueError("close_date 优惠券领取结束时间必须晚于 open_date优惠券领取开始时间 ")
  242. 242
  243. 243 super(Coupon, self).save(*args, **kwargs)

课程相关的13张表

  1. 1 # ######################## 深科技相关 ########################
  2. 2
  3. 3 class ArticleSource(models.Model):
  4. 4 """文章来源"""
  5. 5 name = models.CharField(max_length=64, unique=True)
  6. 6
  7. 7 def __str__(self):
  8. 8 return self.name
  9. 9
  10. 10
  11. 11 class Article(models.Model):
  12. 12 """文章资讯"""
  13. 13 title = models.CharField(max_length=255, unique=True, db_index=True, verbose_name="标题")
  14. 14 source = models.ForeignKey("ArticleSource", verbose_name="来源")
  15. 15 article_type_choices = ((0, '资讯'), (1, '视频'))
  16. 16 article_type = models.SmallIntegerField(choices=article_type_choices, default=0)
  17. 17 brief = models.TextField(max_length=512, verbose_name="摘要")
  18. 18 head_img = models.CharField(max_length=255)
  19. 19 content = models.TextField(verbose_name="文章正文")
  20. 20 pub_date = models.DateTimeField(verbose_name="上架日期")
  21. 21 offline_date = models.DateTimeField(verbose_name="下架日期")
  22. 22 status_choices = ((0, '在线'), (1, '下线'))
  23. 23 status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="状态")
  24. 24 order = models.SmallIntegerField(default=0, verbose_name="权重", help_text="文章想置顶,可以把数字调大,不要超过1000")
  25. 25 vid = models.CharField(max_length=128, verbose_name="视频VID", help_text="文章类型是视频, 则需要添加视频VID", blank=True, null=True)
  26. 26 comment_num = models.SmallIntegerField(default=0, verbose_name="评论数")
  27. 27 agree_num = models.SmallIntegerField(default=0, verbose_name="点赞数")
  28. 28 view_num = models.SmallIntegerField(default=0, verbose_name="观看数")
  29. 29 collect_num = models.SmallIntegerField(default=0, verbose_name="收藏数")
  30. 30
  31. 31 tags = models.ManyToManyField("Tags", blank=True, verbose_name="标签")
  32. 32 date = models.DateTimeField(auto_now_add=True, verbose_name="创建日期")
  33. 33
  34. 34 position_choices = ((0, '信息流'), (1, 'banner大图'), (2, 'banner小图'))
  35. 35 position = models.SmallIntegerField(choices=position_choices, default=0, verbose_name="位置")
  36. 36 comment = GenericRelation("Comment") # 用于GenericForeignKey反向查询, 不会生成表字段,切勿删除,如有疑问请联系老村长
  37. 37
  38. 38 def __str__(self):
  39. 39 return "%s-%s" % (self.source, self.title)
  40. 40
  41. 41
  42. 42 class Collection(models.Model):
  43. 43 """收藏"""
  44. 44 content_type = models.ForeignKey(ContentType)
  45. 45 object_id = models.PositiveIntegerField()
  46. 46 content_object = GenericForeignKey('content_type', 'object_id')
  47. 47
  48. 48 account = models.ForeignKey("Account")
  49. 49 date = models.DateTimeField(auto_now_add=True)
  50. 50
  51. 51 class Meta:
  52. 52 unique_together = ('content_type', 'object_id', 'account')
  53. 53
  54. 54
  55. 55 # 深科技评论和视频评论
  56. 56 class Comment(models.Model):
  57. 57 """通用的评论表: 课程评论 """
  58. 58 content_type = models.ForeignKey(ContentType, blank=True, null=True, verbose_name="类型")
  59. 59 object_id = models.PositiveIntegerField(blank=True, null=True)
  60. 60 content_object = GenericForeignKey('content_type', 'object_id')
  61. 61
  62. 62 p_node = models.ForeignKey("self", blank=True, null=True, verbose_name="父级评论")
  63. 63 content = models.TextField(max_length=1024)
  64. 64 account = models.ForeignKey("Account", verbose_name="会员名")
  65. 65 disagree_number = models.IntegerField(default=0, verbose_name="踩")
  66. 66 agree_number = models.IntegerField(default=0, verbose_name="赞同数")
  67. 67 date = models.DateTimeField(auto_now_add=True)
  68. 68
  69. 69 def __str__(self):
  70. 70 return self.content

深科技相关

  1. 1 # ######################## 购买课程相关 ########################
  2. 2
  3. 3 class EnrolledCourse(models.Model):
  4. 4 """已报名课程,不包括学位课程"""
  5. 5 account = models.ForeignKey("Account")
  6. 6 course = models.ForeignKey("Course", limit_choices_to=~Q(course_type=2))
  7. 7 enrolled_date = models.DateTimeField(auto_now_add=True)
  8. 8 valid_begin_date = models.DateField(verbose_name="有效期开始自")
  9. 9 valid_end_date = models.DateField(verbose_name="有效期结束至")
  10. 10 status_choices = ((0, '已开通'), (1, '已过期'))
  11. 11 status = models.SmallIntegerField(choices=status_choices, default=0)
  12. 12 order_detail = models.OneToOneField("OrderDetail") # 使订单购买后支持 课程评价
  13. 13
  14. 14 # order = models.ForeignKey("Order",blank=True,null=True)
  15. 15
  16. 16 def __str__(self):
  17. 17 return "%s:%s" % (self.account, self.course)
  18. 18
  19. 19
  20. 20 class DegreeRegistrationForm(models.Model):
  21. 21 """学位课程报名表"""
  22. 22 enrolled_degree = models.OneToOneField("EnrolledDegreeCourse")
  23. 23 current_company = models.CharField(max_length=64, )
  24. 24 current_position = models.CharField(max_length=64, )
  25. 25 current_salary = models.IntegerField()
  26. 26 work_experience_choices = (
  27. 27 (0, "应届生"),
  28. 28 (1, "1年"),
  29. 29 (2, "2年"),
  30. 30 (3, "3年"),
  31. 31 (4, "4年"),
  32. 32 (5, "5年"),
  33. 33 (6, "6年"),
  34. 34 (7, "7年"),
  35. 35 (8, "8年"),
  36. 36 (9, "9年"),
  37. 37 (10, "10年"),
  38. 38 (11, "超过10年"),
  39. 39 )
  40. 40 work_experience = models.IntegerField()
  41. 41 open_module = models.BooleanField("是否开通第1模块", default=True)
  42. 42 stu_specified_mentor = models.CharField("学员自行指定的导师名", max_length=32, blank=True, null=True)
  43. 43 study_plan_choices = ((0, "1-2小时/天"),
  44. 44 (1, "2-3小时/天"),
  45. 45 (2, "3-5小时/天"),
  46. 46 (3, "5小时+/天"),
  47. 47 )
  48. 48 study_plan = models.SmallIntegerField(choices=study_plan_choices, default=1)
  49. 49 why_take_this_course = models.TextField("报此课程原因", max_length=1024)
  50. 50 why_choose_us = models.TextField("为何选路飞", max_length=1024)
  51. 51 your_expectation = models.TextField("你的期待", max_length=1024)
  52. 52 memo = models.CharField(max_length=255, blank=True, null=True)
  53. 53
  54. 54 def __str__(self):
  55. 55 return "%s" % self.enrolled_degree
  56. 56
  57. 57
  58. 58 class EnrolledDegreeCourse(models.Model):
  59. 59 """已报名的学位课程"""
  60. 60 account = models.ForeignKey("Account")
  61. 61 degree_course = models.ForeignKey("DegreeCourse")
  62. 62 enrolled_date = models.DateTimeField(auto_now_add=True)
  63. 63 valid_begin_date = models.DateField(verbose_name="有效期开始自", blank=True, null=True) # 开通第一个模块时,再添加课程有效期,2年
  64. 64 valid_end_date = models.DateField(verbose_name="有效期结束至", blank=True, null=True)
  65. 65 status_choices = (
  66. 66 (0, '在学中'),
  67. 67 (1, '休学中'),
  68. 68 (2, '已毕业'),
  69. 69 (3, '超时结业'),
  70. 70 (4, '未开始'),
  71. 71 # (3, '其它'),
  72. 72 )
  73. 73 study_status = models.SmallIntegerField(choices=status_choices, default=0)
  74. 74 mentor = models.ForeignKey("Account", verbose_name="导师", related_name='my_students',
  75. 75 blank=True, null=True, limit_choices_to={'role': 1})
  76. 76 mentor_fee_balance = models.PositiveIntegerField("导师费用余额", help_text="这个学员的导师费用,每有惩罚,需在此字段同时扣除")
  77. 77 order_detail = models.OneToOneField("OrderDetail") # 使订单购买后支持填写报名表
  78. 78
  79. 79 def __str__(self):
  80. 80 return "%s:%s" % (self.account, self.degree_course)
  81. 81
  82. 82 class Meta:
  83. 83 unique_together = ('account', 'degree_course')
  84. 84
  85. 85
  86. 86 class Coupon(models.Model):
  87. 87 """优惠券生成规则"""
  88. 88 name = models.CharField(max_length=64, verbose_name="活动名称")
  89. 89 brief = models.TextField(blank=True, null=True, verbose_name="优惠券介绍")
  90. 90 coupon_type_choices = ((0, '通用券'), (1, '满减券'), (2, '折扣券'))
  91. 91 coupon_type = models.SmallIntegerField(choices=coupon_type_choices, default=0, verbose_name="券类型")
  92. 92
  93. 93 money_equivalent_value = models.IntegerField(verbose_name="等值货币")
  94. 94 off_percent = models.PositiveSmallIntegerField("折扣百分比", help_text="只针对折扣券,例7.9折,写79", blank=True, null=True)
  95. 95 minimum_consume = models.PositiveIntegerField("最低消费", default=0, help_text="仅在满减券时填写此字段")
  96. 96
  97. 97 content_type = models.ForeignKey(ContentType, blank=True, null=True)
  98. 98 object_id = models.PositiveIntegerField("绑定课程", blank=True, null=True, help_text="可以把优惠券跟课程绑定")
  99. 99 content_object = GenericForeignKey('content_type', 'object_id')
  100. 100
  101. 101 quantity = models.PositiveIntegerField("数量(张)", default=1)
  102. 102 open_date = models.DateField("优惠券领取开始时间")
  103. 103 close_date = models.DateField("优惠券领取结束时间")
  104. 104 valid_begin_date = models.DateField(verbose_name="有效期开始时间", blank=True, null=True)
  105. 105 valid_end_date = models.DateField(verbose_name="有效结束时间", blank=True, null=True)
  106. 106 coupon_valid_days = models.PositiveIntegerField(verbose_name="优惠券有效期(天)", blank=True, null=True,
  107. 107 help_text="自券被领时开始算起")
  108. 108 date = models.DateTimeField(auto_now_add=True)
  109. 109
  110. 110 def __str__(self):
  111. 111 return "%s(%s)" % (self.get_coupon_type_display(), self.name)
  112. 112
  113. 113 def save(self, *args, **kwargs):
  114. 114 if not self.coupon_valid_days or (self.valid_begin_date and self.valid_end_date):
  115. 115 if self.valid_begin_date and self.valid_end_date:
  116. 116 if self.valid_end_date <= self.valid_begin_date:
  117. 117 raise ValueError("valid_end_date 有效期结束日期必须晚于 valid_begin_date ")
  118. 118 if self.coupon_valid_days == 0:
  119. 119 raise ValueError("coupon_valid_days 有效期不能为0")
  120. 120 if self.close_date < self.open_date:
  121. 121 raise ValueError("close_date 优惠券领取结束时间必须晚于 open_date优惠券领取开始时间 ")
  122. 122
  123. 123 super(Coupon, self).save(*args, **kwargs)
  124. 124
  125. 125
  126. 126 class CouponRecord(models.Model):
  127. 127 """优惠券发放、消费纪录"""
  128. 128 coupon = models.ForeignKey("Coupon")
  129. 129 #number = models.CharField(max_length=64, unique=True)
  130. 130 account = models.ForeignKey("Account", verbose_name="拥有者")
  131. 131 status_choices = ((0, '未使用'), (1, '已使用'), (2, '已过期'),)
  132. 132 status = models.SmallIntegerField(choices=status_choices, default=0)
  133. 133 get_time = models.DateTimeField(verbose_name="领取时间", help_text="用户领取时间")
  134. 134 used_time = models.DateTimeField(blank=True, null=True, verbose_name="使用时间")
  135. 135 order = models.ForeignKey("Order", blank=True, null=True, verbose_name="关联订单") # 一个订单可以有多个优惠券
  136. 136
  137. 137
  138. 138 class Order(models.Model):
  139. 139 """订单"""
  140. 140 payment_type_choices = ((0, '微信'), (1, '支付宝'), (2, '优惠码'), (3, '贝里'))
  141. 141 payment_type = models.SmallIntegerField(choices=payment_type_choices)
  142. 142 payment_number = models.CharField(max_length=128, verbose_name="支付第3方订单号", null=True, blank=True)
  143. 143 order_number = models.CharField(max_length=128, verbose_name="订单号", unique=True) # 考虑到订单合并支付的问题
  144. 144 account = models.ForeignKey("Account")
  145. 145 actual_amount = models.FloatField(verbose_name="实付金额")
  146. 146
  147. 147 status_choices = ((0, '交易成功'), (1, '待支付'), (2, '退费申请中'), (3, '已退费'), (4, '主动取消'), (5, '超时取消'))
  148. 148 status = models.SmallIntegerField(choices=status_choices, verbose_name="状态")
  149. 149 date = models.DateTimeField(auto_now_add=True, verbose_name="订单生成时间")
  150. 150 pay_time = models.DateTimeField(blank=True, null=True, verbose_name="付款时间")
  151. 151 cancel_time = models.DateTimeField(blank=True, null=True, verbose_name="订单取消时间")
  152. 152
  153. 153 def __str__(self):
  154. 154 return "%s" % self.order_number
  155. 155
  156. 156
  157. 157 class OrderDetail(models.Model):
  158. 158 """订单详情"""
  159. 159 order = models.ForeignKey("Order")
  160. 160
  161. 161 content_type = models.ForeignKey(ContentType) # 可关联普通课程或学位
  162. 162 object_id = models.PositiveIntegerField()
  163. 163 content_object = GenericForeignKey('content_type', 'object_id')
  164. 164
  165. 165 original_price = models.FloatField("课程原价")
  166. 166 price = models.FloatField("折后价格")
  167. 167 content = models.CharField(max_length=255, blank=True, null=True) # ?
  168. 168 valid_period_display = models.CharField("有效期显示", max_length=32) # 在订单页显示
  169. 169 valid_period = models.PositiveIntegerField("有效期(days)") # 课程有效期
  170. 170 memo = models.CharField(max_length=255, blank=True, null=True)
  171. 171
  172. 172 # def __str__(self):
  173. 173 # return "%s - %s - %s" % (self.order, self.content_type, self.price)
  174. 174
  175. 175 class Meta:
  176. 176 # unique_together = ("order", 'course')
  177. 177 unique_together = ("order", 'content_type', 'object_id')
  178. 178
  179. 179
  180. 180 class TransactionRecord(models.Model):
  181. 181 """贝里交易纪录"""
  182. 182 account = models.ForeignKey("Account")
  183. 183 amount = models.IntegerField("金额")
  184. 184 balance = models.IntegerField("账户余额")
  185. 185 transaction_type_choices = ((0, '收入'), (1, '支出'), (2, '退款'), (3, "提现")) # 2 为了处理 订单过期未支付时,锁定期贝里的回退
  186. 186 transaction_type = models.SmallIntegerField(choices=transaction_type_choices)
  187. 187
  188. 188 content_type = models.ForeignKey(ContentType, blank=True, null=True)
  189. 189 object_id = models.PositiveIntegerField(blank=True, null=True, verbose_name="关联对象")
  190. 190 content_object = GenericForeignKey('content_type', 'object_id')
  191. 191
  192. 192 transaction_number = models.CharField(unique=True, verbose_name="流水号", max_length=128)
  193. 193 date = models.DateTimeField(auto_now_add=True)
  194. 194 memo = models.CharField(max_length=128, blank=True, null=True)
  195. 195
  196. 196 def __str__(self):
  197. 197 return "%s" % self.transaction_number

购买课程相关的8张表

  1. 1 class Homework(models.Model):
  2. 2 chapter = models.ForeignKey("CourseChapter")
  3. 3 title = models.CharField(max_length=128, verbose_name="作业题目")
  4. 4 order = models.PositiveSmallIntegerField("作业顺序", help_text="同一课程的每个作业之前的order值间隔1-2个数")
  5. 5 homework_type_choices = ((0, '作业'), (1, '模块通关考核'))
  6. 6 homework_type = models.SmallIntegerField(choices=homework_type_choices, default=0)
  7. 7 requirement = models.TextField(max_length=1024, verbose_name="作业需求")
  8. 8 threshold = models.TextField(max_length=1024, verbose_name="踩分点")
  9. 9 recommend_period = models.PositiveSmallIntegerField("推荐完成周期(天)", default=7)
  10. 10 scholarship_value = models.PositiveSmallIntegerField("为该作业分配的奖学金(贝里)")
  11. 11 note = models.TextField(blank=True, null=True)
  12. 12 enabled = models.BooleanField(default=True, help_text="本作业如果后期不需要了,不想让学员看到,可以设置为False")
  13. 13
  14. 14 class Meta:
  15. 15 unique_together = ("chapter", "title")
  16. 16
  17. 17 def __str__(self):
  18. 18 return "%s - %s" % (self.chapter, self.title)
  19. 19
  20. 20
  21. 21 class Teacher(models.Model):
  22. 22 """讲师、导师表"""
  23. 23 name = models.CharField(max_length=32)
  24. 24 role_choices = ((0, '讲师'), (1, '导师'))
  25. 25 role = models.SmallIntegerField(choices=role_choices, default=0)
  26. 26 title = models.CharField(max_length=64, verbose_name="职位、职称")
  27. 27 signature = models.CharField(max_length=255, help_text="导师签名", blank=True, null=True)
  28. 28 image = models.CharField(max_length=128)
  29. 29 brief = models.TextField(max_length=1024)
  30. 30
  31. 31 def __str__(self):
  32. 32 return self.name
  33. 33
  34. 34
  35. 35 # 普通课购买课程后,我的订单中去评价。
  36. 36 class CourseReview(models.Model):
  37. 37 """课程评价"""
  38. 38 enrolled_course = models.OneToOneField("EnrolledCourse")
  39. 39 about_teacher = models.FloatField(default=0, verbose_name="讲师讲解是否清晰")
  40. 40 about_video = models.FloatField(default=0, verbose_name="内容实用")
  41. 41 about_course = models.FloatField(default=0, verbose_name="课程内容通俗易懂")
  42. 42 review = models.TextField(max_length=1024, verbose_name="评价")
  43. 43 disagree_number = models.IntegerField(default=0, verbose_name="踩")
  44. 44 agree_number = models.IntegerField(default=0, verbose_name="赞同数")
  45. 45 tags = models.ManyToManyField("Tags", blank=True, verbose_name="标签")
  46. 46 date = models.DateTimeField(auto_now_add=True, verbose_name="评价日期")
  47. 47 is_recommend = models.BooleanField("热评推荐", default=False)
  48. 48 hide = models.BooleanField("不在前端页面显示此条评价", default=False)
  49. 49
  50. 50 def __str__(self):
  51. 51 return "%s-%s" % (self.enrolled_course.course, self.review)
  52. 52
  53. 53
  54. 54 # 学位课购买课程后,我的订单中去天报名表,然后就编程去学习(以后去评价)。
  55. 55 class DegreeCourseReview(models.Model):
  56. 56 """学位课程评价
  57. 57 为了以后可以定制单独的评价内容,所以不与普通课程的评价混在一起,单独建表
  58. 58 """
  59. 59 enrolled_course = models.ForeignKey("EnrolledDegreeCourse")
  60. 60 course = models.ForeignKey("Course", verbose_name="评价学位模块", blank=True, null=True,
  61. 61 help_text="不填写即代表评价整个学位课程", limit_choices_to={'course_type': 2})
  62. 62 about_teacher = models.FloatField(default=0, verbose_name="讲师讲解是否清晰")
  63. 63 about_video = models.FloatField(default=0, verbose_name="视频质量")
  64. 64 about_course = models.FloatField(default=0, verbose_name="课程")
  65. 65 review = models.TextField(max_length=1024, verbose_name="评价")
  66. 66 disagree_number = models.IntegerField(default=0, verbose_name="踩")
  67. 67 agree_number = models.IntegerField(default=0, verbose_name="赞同数")
  68. 68 tags = models.ManyToManyField("Tags", blank=True, verbose_name="标签")
  69. 69 date = models.DateTimeField(auto_now_add=True, verbose_name="评价日期")
  70. 70 is_recommend = models.BooleanField("热评推荐", default=False)
  71. 71 hide = models.BooleanField("不在前端页面显示此条评价", default=False)
  72. 72
  73. 73 def __str__(self):
  74. 74 return "%s-%s" % (self.enrolled_course, self.review)
  75. 75
  76. 76
  77. 77
  78. 78 # 购买学位课后,为每个学生每个模块会立刻生成一条学习纪录(未开通)
  79. 79 class StudyRecord(models.Model):
  80. 80 """学位课程的模块学习进度
  81. 81 报名学位课程后,每个模块会立刻生成一条学习纪录
  82. 82 """
  83. 83 enrolled_degree_course = models.ForeignKey("EnrolledDegreeCourse")
  84. 84 course_module = models.ForeignKey("Course", verbose_name="学位模块", limit_choices_to={'course_type': 2})
  85. 85 open_date = models.DateField(blank=True, null=True, verbose_name="开通日期")
  86. 86 end_date = models.DateField(blank=True, null=True, verbose_name="完成日期")
  87. 87 status_choices = ((2, '在学'), (1, '未开通'), (0, '已完成'))
  88. 88 status = models.SmallIntegerField(choices=status_choices, default=1)
  89. 89
  90. 90 class Meta:
  91. 91 unique_together = ('enrolled_degree_course', 'course_module')
  92. 92
  93. 93 def __str__(self):
  94. 94 return '%s-%s' % (self.enrolled_degree_course, self.course_module)
  95. 95
  96. 96 def save(self, *args, **kwargs):
  97. 97 if self.course_module.degree_course_id != self.enrolled_degree_course.degree_course_id:
  98. 98 raise ValueError("学员要开通的模块必须与其报名的学位课程一致!")
  99. 99
  100. 100 super(StudyRecord, self).save(*args, **kwargs)
  101. 101
  102. 102
  103. 103 # 为学生开通一个模块
  104. 104 class CourseSchedule(models.Model):
  105. 105 """课程进度计划表,针对学位课程,每开通一个模块,就为这个学员生成这个模块的推荐学习计划表,后面的奖惩均按此表进行"""
  106. 106 study_record = models.ForeignKey("StudyRecord")
  107. 107 homework = models.ForeignKey("Homework")
  108. 108 recommend_date = models.DateField("推荐交作业日期")
  109. 109
  110. 110 def __str__(self):
  111. 111 return "%s - %s - %s " % (self.study_record, self.homework, self.recommend_date)
  112. 112
  113. 113 class Meta:
  114. 114 unique_together = ('study_record', 'homework')
  115. 115
  116. 116
  117. 117 # 学生交作业
  118. 118 class HomeworkRecord(models.Model):
  119. 119 """学员作业记录及成绩"""
  120. 120 homework = models.ForeignKey("Homework")
  121. 121 student = models.ForeignKey("EnrolledDegreeCourse", verbose_name="学生")
  122. 122 score_choices = (
  123. 123 (100, 'A+'),
  124. 124 (90, 'A'),
  125. 125 (85, 'B+'),
  126. 126 (80, 'B'),
  127. 127 (70, 'B-'),
  128. 128 (60, 'C+'),
  129. 129 (50, 'C'),
  130. 130 (40, 'C-'),
  131. 131 (-1, 'D'),
  132. 132 (0, 'N/A'),
  133. 133 (-100, 'COPY'),
  134. 134 )
  135. 135 score = models.SmallIntegerField(verbose_name="分数", choices=score_choices, null=True, blank=True)
  136. 136 mentor = models.ForeignKey("Account", related_name="my_stu_homework_record", limit_choices_to={'role': 1},
  137. 137 verbose_name="导师")
  138. 138 mentor_comment = models.TextField(verbose_name="导师批注", blank=True, null=True) # 导师
  139. 139 status_choice = (
  140. 140 (0, '待批改'),
  141. 141 (1, '已通过'),
  142. 142 (2, '不合格'),
  143. 143 )
  144. 144 status = models.SmallIntegerField(verbose_name='作业状态', choices=status_choice, default=0)
  145. 145
  146. 146 submit_num = models.SmallIntegerField(verbose_name='提交次数', default=0)
  147. 147 correct_date = models.DateTimeField('备注日期', blank=True, null=True)
  148. 148 note = models.TextField(blank=True, null=True)
  149. 149 date = models.DateTimeField("作业提交日期", auto_now_add=True)
  150. 150
  151. 151 check_date = models.DateTimeField("批改日期", null=True, blank=True)
  152. 152
  153. 153 update_time = models.DateTimeField(auto_now=True, verbose_name="提交日期")
  154. 154
  155. 155 # homework_path = models.CharField(verbose_name='作业路径', max_length=256,blank=True,null=True) 作业路径可以动态拿到,没必要存
  156. 156
  157. 157 reward_choice = (
  158. 158 (0, '新提交'),
  159. 159 (1, '按时提交'),
  160. 160 (2, '未按时提交'),
  161. 161 (3, '成绩已奖励'),
  162. 162 (4, '成绩已处罚'),
  163. 163 (5, '未作按时检测'),
  164. 164 )
  165. 165 reward_status = models.SmallIntegerField(verbose_name='作业记录奖惩状态', default=0)
  166. 166
  167. 167 def __str__(self):
  168. 168 return "%s %s" % (self.homework, self.student)
  169. 169
  170. 170 class Meta:
  171. 171 unique_together = ("homework", "student")
  172. 172
  173. 173
  174. 174 # 导师跟进记录
  175. 175 class StuFollowUpRecord(models.Model):
  176. 176 """学员跟进记录"""
  177. 177 enrolled_degree_course = models.ForeignKey("EnrolledDegreeCourse", verbose_name="学生")
  178. 178 mentor = models.ForeignKey("Account", related_name='mentor', limit_choices_to={'role': 1}, verbose_name="导师")
  179. 179 followup_tool_choices = ((0, 'QQ'), (1, '微信'), (2, '电话'), (3, '系统通知'))
  180. 180 followup_tool = models.SmallIntegerField(choices=followup_tool_choices, default=1)
  181. 181 record = models.TextField(verbose_name="跟进记录")
  182. 182 attachment_path = models.CharField(max_length=128, blank=True, null=True, verbose_name="附件路径", help_text="跟进记录的截图等")
  183. 183 date = models.DateTimeField(auto_now_add=True)
  184. 184
  185. 185 def __str__(self):
  186. 186 return "%s --%s --%s" % (self.enrolled_degree_course, self.record, self.date)

学位课优惠相关的表

K12(在线学习的平台)的更多相关文章

  1. 一个很好的MySQL在线学习平台

    一个很好的MySQL在线学习平台 https://www.techonthenet.com/sql/

  2. 机器人操作系统(ROS)在线实训平台学习实验指南

    机器人操作系统(ROS)在线学习指南       在高校开设ROS相关课程已经积累了一年多的经验,由于自动化类专业在课程安排中不同于计算机相关专业,通常没有Linux相关的课程基础,直接上手ROS较为 ...

  3. 在线学习体验大PK 云智慧发布在线教育网站性能监测报告

    互联网不但改变了我们的生活.娱乐和消费方式,也推动各行各业进行着快速变革,越来越多的职场人士必须通过不断的学习.充电才能跟上行业发展的步伐,获得职业的提升,而这也引发了国内教育市场的爆炸式发展.据统计 ...

  4. MCtalk对话学吧课堂:真正的K12在线教育才刚刚开始

    课堂之外的在线教育已经被大部分家庭所熟知,既涌现出了VIPKID等行业独角兽,也有大量致力于科技改变教育的新兴机构获得了快速成长.成立于2014年的学吧课堂就是专注在K12在线教育领域的创新机构,他们 ...

  5. 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代

    2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...

  6. HTML5初学者福利!11个在线学习网站推荐

    HTML5初学者福利!11个在线学习网站推荐 HTML5的强大及流行趋势,让更多的人想要系统的对它进行学习.而大多数人获取HTML5知识的重要途径都是网络,不过面对五花八门的搜索结果,是不是觉得摸不着 ...

  7. 初学者福音——10个最佳APP开发入门在线学习网站

    根据Payscale的调查显示,现在的APP开发人员的年薪达到:$66,851.这也是为什么那么多初学的开发都想跻身到APP开发这行业的主要原因之一.每当你打开App Store时候,看着琳琅满目的A ...

  8. 在线学习Java免费资源推荐

    你想学习Java吗?来对地方了!这篇文章将会介绍很多高质量的免费资源,包括网页.论坛.电子书和速查表. Java是一种面向对象的编程语言,拥有独立.多线程.安全.动态和健壮的特点.归功于其多功能的特点 ...

  9. 微软大礼包 | 集合在线学习资源,助你秒变AI达人

    编者按:人工智能的浪潮正如火如荼地袭来,未来人工智能将大有所为,人们的生活轨迹也正在技术不断向前推进的过程中逐渐改变.人工智能不是科研人员或开发人员的专属,微软希望能够将人工智能带给每个人,从开发者到 ...

随机推荐

  1. respond.js第六行 SCRIPT5: 拒绝访问。跨域问题

    问题描述:respond.js第六行 SCRIPT5: 拒绝访问.昨天为学弟学妹讲bootstrap,说到对ie78的兼容问题,解决办法中有引入html5shiv.js和respond.js两个文件夹 ...

  2. LeetCode OJ :Remove Linked List Elements (移除链表元素)

    Remove all elements from a linked list of integers that have value val. ExampleGiven: 1 --> 2 --& ...

  3. hp g6 2328tx 加装ssd 机械硬盘安装到光驱位置 问题小结

    惠普 g6 笔记本从13年入手至今,三年有余,性能啥的开始跟不上了,所有入手了一块ssd,闪迪(sanDisk)加强版 240G的固态硬盘,准备升下级.狗东下午下单,第二天早上7点多到的,把老硬盘换下 ...

  4. react bootstrap-loader

    1.install npm install bootstrap-loader jquery resolve-url-loader 2.webpack.config.js entry: ['bootst ...

  5. 2017.11.18 IAP下载(STM8,PIC,STM32)

    客户要求用IAP下载,mark一下,客户还给了stm32的引导码.仅供参考. 1 PIC单片机的IAP  2 STm32 IAP https://www.cnblogs.com/WeyneChen/p ...

  6. DRF 权限的流程

    DRF 权限的流程 django rest framework,入口是 dispatch,然后依次 --->>封装请求--->>处理版本--->>>认证--- ...

  7. canvas 创建渐变图形

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  8. windows获取屏幕显示比例 读取注册表法

    static int GetDesktopScale() { ; HINSTANCE hUser32 = LoadLibrary(L"user32.dll"); if (hUser ...

  9. MpVue解析

    前言 mpvue是一款使用Vue.js开发微信小程序的前端框架.使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为H5和小程序提供了代码复用的能力.如果想将 H5 项目改造为小程序,或开发 ...

  10. nginx 转发 由于php语法错误 导致的 50x

    server {        listen 8008;        root /root/php-test;        index index.php index.html index.htm ...