十一、课程章节功能

1、前端页面配置

  将课程章节页面course-video.html拷贝到templates目录下。

  继承base.html页面,重写需要block的地方:

2、课程章节接口

1 class CourseLessonView(View):
2     """课程章节"""
3     def get(self, request, course_id):
4         # 根据前端传递的课程id找到对应的课程
5         course = Course.objects.get(id=int(course_id))
6
7         return render(request, 'course-video.html', {
8             'course': course
9         })

  配置url:

1 from .views import CourseLessonView
2
3 urlpatterns = [
4     re_path('lesson/(?P<course_id>\d+)/', CourseLessonView.as_view(), name='course_lesson'),  # 课程章节
5 ]

  然后在课程详情页面修改点击开始学习后进入课程章节页面的url:

  修改课程章节页面面包屑中的url跳转:

  在章节中有视频信息,需要给视频信息添加一个访问地址字段,在视频的model中添加视频访问地址的字段:

 1 class Video(models.Model):
 2     """视频"""
 3     lesson = models.ForeignKey(Lesson, verbose_name='章节', on_delete=models.CASCADE)
 4     name = models.CharField('视频名', max_length=100)
 5     url = models.CharField('访问地址', default='', max_length=200)
 6     add_time = models.DateTimeField('添加时间', default=datetime.now)
 7
 8     class Meta:
 9         verbose_name = '视频'
10         verbose_name_plural = verbose_name

  迁移数据库。

  然后在后台中添加章节和视频的数据。

  在课程章节页面需要有课程的所有章节、以及视频,所以需要在课程的model中获取所有的章节和章节的model中获取所有的视频以及视频的model中添加一个学习时长字段:

 1 class Course(models.Model):
 2     """课程"""
 3     DEGREE_CHOICES = (
 4         ('cj', '初级'),
 5         ('zj', '中级'),
 6         ('gj', '高级')
 7     )
 8
 9     name = models.CharField('课程名', max_length=50)
10     desc = models.CharField('课程描述', max_length=300)
11     detail = models.TextField('课程详情')
12     degree = models.CharField('课程难度', choices=DEGREE_CHOICES, max_length=2)
13     learn_times = models.IntegerField('学习时长(分钟数)', default=0)
14     students = models.IntegerField('学习人数', default=0)
15     fav_nums = models.IntegerField('收藏人数', default=0)
16     click_nums = models.IntegerField('点击数', default=0)
17     image = models.ImageField('封面图', upload_to='courses/%Y/%m', max_length=100)
18     course_org = models.ForeignKey(CourseOrg, verbose_name='所属机构', on_delete=models.CASCADE, null=True, blank=True)
19     category = models.CharField('课程类别', max_length=20, default='')
20     tag = models.CharField('标签', max_length=10, default='')
21     add_time = models.DateTimeField('添加时间', default=datetime.now)
22
23     class Meta:
24         verbose_name = '课程'
25         verbose_name_plural = verbose_name
26
27     # 获取章节数
28     def get_zj_nums(self):
29         return self.lesson_set.all().count()
30
31     # 获取学习用户
32     def get_learn_users(self):
33         return self.usercourse_set.all()[:5]
34
35     # 获取章节
36     def get_course_lesson(self):
37         return self.lesson_set.all()
38
39     def __str__(self):
40         return self.name
41
42
43 class Lesson(models.Model):
44     """章节"""
45     course = models.ForeignKey(Course, verbose_name='课程', on_delete=models.CASCADE)
46     name = models.CharField('章节名', max_length=100)
47     add_time = models.DateTimeField('添加时间', default=datetime.now)
48
49     class Meta:
50         verbose_name = '章节'
51         verbose_name_plural = verbose_name
52
53     # 获取所有的视频
54     def get_lesson_video(self):
55         return self.video_set.all()
56
57     def __str__(self):
58         return '《{}》课程的章节:{}'.format(self.course.name, self.name)
59
60
61 class Video(models.Model):
62     """视频"""
63     lesson = models.ForeignKey(Lesson, verbose_name='章节', on_delete=models.CASCADE)
64     name = models.CharField('视频名', max_length=100)
65     url = models.CharField('访问地址', default='', max_length=200)
66     learn_times = models.IntegerField('学习时长(分钟数)', default=0)
67     add_time = models.DateTimeField('添加时间', default=datetime.now)
68
69     class Meta:
70         verbose_name = '视频'
71         verbose_name_plural = verbose_name

View Code

  然后迁移数据库。

  修改课程章节页面中显示课程章节及视频的代码:

  刷新之后即可看到后台添加的视频章节及视频信息。

  在课程章节页面右侧有资源下载,首先在后台添加资源文件,然后完善课程章节接口获取资源文件的逻辑:

 1 class CourseLessonView(View):
 2     """课程章节"""
 3     def get(self, request, course_id):
 4         # 根据前端传递的课程id找到对应的课程
 5         course = Course.objects.get(id=int(course_id))
 6
 7         # 获取所有的资源文件
 8         all_resources = CourseResourse.objects.filter(course=course)
 9
10         return render(request, 'course-video.html', {
11             'course': course,
12             'all_resources': all_resources
13         })

  修改课程章节页面中显示资源下载的代码:

  然后修改章节上面显示课程信息的相关代码:

  在资源下载下面有讲师提示,需要在课程的model中添加教师的外键,还有课程须知以及老师告诉你的两个字段:

 1 class Course(models.Model):
 2     """课程"""
 3     DEGREE_CHOICES = (
 4         ('cj', '初级'),
 5         ('zj', '中级'),
 6         ('gj', '高级')
 7     )
 8
 9     name = models.CharField('课程名', max_length=50)
10     desc = models.CharField('课程描述', max_length=300)
11     detail = models.TextField('课程详情')
12     degree = models.CharField('课程难度', choices=DEGREE_CHOICES, max_length=2)
13     learn_times = models.IntegerField('学习时长(分钟数)', default=0)
14     students = models.IntegerField('学习人数', default=0)
15     fav_nums = models.IntegerField('收藏人数', default=0)
16     click_nums = models.IntegerField('点击数', default=0)
17     image = models.ImageField('封面图', upload_to='courses/%Y/%m', max_length=100)
18     course_org = models.ForeignKey(CourseOrg, verbose_name='所属机构', on_delete=models.CASCADE, null=True, blank=True)
19     category = models.CharField('课程类别', max_length=20, default='')
20     tag = models.CharField('标签', max_length=10, default='')
21     teacher = models.ForeignKey(Teacher, verbose_name='机构讲师', on_delete=models.CASCADE, null=True, blank=True)
22     courseneed_know = models.CharField('课程须知', max_length=300, default='')
23     teacher_tellyou = models.CharField('老师告诉你', max_length=300, default='')
24     add_time = models.DateTimeField('添加时间', default=datetime.now)
25
26     class Meta:
27         verbose_name = '课程'
28         verbose_name_plural = verbose_name
29
30     # 获取章节数
31     def get_zj_nums(self):
32         return self.lesson_set.all().count()
33
34     # 获取学习用户
35     def get_learn_users(self):
36         return self.usercourse_set.all()[:5]
37
38     # 获取章节
39     def get_course_lesson(self):
40         return self.lesson_set.all()
41
42     def __str__(self):
43         return self.name

  迁移数据库,然后在后台的课程中添加讲师,修改课程章节页面中显示讲师提示的代码:

3、相关课程推荐

  在课程章节页面的右侧最下方有相关课程的推荐,首先在课程章节接口中添加相关课程推荐的逻辑:

 1 class CourseLessonView(View):
 2     """课程章节"""
 3     def get(self, request, course_id):
 4         # 根据前端传递的课程id找到对应的课程
 5         course = Course.objects.get(id=int(course_id))
 6
 7         # 获取所有的资源文件
 8         all_resources = CourseResourse.objects.filter(course=course)
 9
10         # 相关课程推荐
11         # 找到学习这门课程的所有用户
12         user_courses = UserCourse.objects.filter(course=course)
13         # 找到学习这门课的所有用户的id
14         user_ids = [user_course.user_id for user_course in user_courses]
15         # 通过所有用户的id,找到所有用户学习过的所有课程
16         all_user_courses = UserCourse.objects.filter(user_id__in=user_ids)
17         # 取出所有课程id
18         course_ids = [all_user_course.course_id for all_user_course in all_user_courses]
19         # 通过所有课程id找到所有的课程,按点击量区5个
20         relate_courses = Course.objects.filter(id__in=course_ids).order_by('-click_nums')[:5]
21
22
23         return render(request, 'course-video.html', {
24             'course': course,
25             'all_resources': all_resources,
26             'relate_courses': relate_courses
27         })

  然后修改课程章节页面中显示相关课程推荐的代码:

十二、课程评论功能

1、前端页面配置

  将课程评论页面course-comment.html拷贝到templates目录下。

  继承base.html页面,重写需要block的地方:

2、课程评论接口

 1 class CourseCommentsView(View):
 2     """课程评论"""
 3     def get(self, request, course_id):
 4         course = Course.objects.get(id=int(course_id))
 5         all_resources = CourseResourse.objects.filter(course=course)
 6
 7         # 获取所有的评论信息
 8         all_comments = CourseComments.objects.all()
 9
10         return render(request, 'course-comment.html', {
11             'course': course,
12             'all_resources': all_resources,
13             'all_comments': all_comments
14         })

  配置url:

1 from .views import CourseCommentsView
2
3 urlpatterns = [
4     re_path('comment/(?P<course_id>\d+)/', CourseCommentsView.as_view(), name='course_comment'),  # 课程评论
5 ]

  然后修改课程章节页面跳转到课程评论页面的url:

  课程评论页面右侧的课程资源下载和讲师提示的代码和课程章节页面的代码一样,只需要拷贝过来即可。

  添加评论功能需要重新写一个添加评论的接口:

 1 class AddCommentsView(View):
 2     """添加评论"""
 3     def post(self, request):
 4         # 未登录不能评论,返回json数据由前端返回登录页面
 5         if not request.user.is_authenticated:
 6             return HttpResponse('{"status": "fail", "msg": "用户未登录"}', content_type='application/json')
 7
 8         # 从request中获取课程的id和评论信息
 9         course_id = request.POST.get('course_id', 0)
10         comments = request.POST.get('comments', '')
11
12         # 将评论信息保存到数据库
13         if int(course_id)>0 and comments:
14             course_comments = CourseComments()
15             course = Course.objects.get(id=int(course_id))
16             course_comments.course = course
17             course_comments.comments = comments
18             course_comments.user = request.user
19             course_comments.save()
20
21             return HttpResponse('{"status": "success", "msg": "评论成功"}', content_type='application/json')
22         else:
23             return HttpResponse('{"status": "fail", "msg": "评论失败"}', content_type='application/json')

  配置url:

1 from .views import AddCommentsView
2
3 urlpatterns = [
4     path('add_comment/', AddCommentsView.as_view(), name='add_comment'),  # 添加评论
5 ]

  评论信息是通过script代码通过ajax异步提交的,需要在课程评论页面的最后加上script代码:

 1 {% block custom_js %}
 2     <script type="text/javascript">
 3     //添加评论
 4     $('#js-pl-submit').on('click', function(){
 5         var comments = $("#js-pl-textarea").val()
 6         if(comments == ""){
 7             alert("评论不能为空")
 8             return
 9         }
10         $.ajax({
11             cache: false,
12             type: "POST",
13             url:"{% url 'course:add_comment' %}",
14             data:{'course_id':{{ course.id }}, 'comments':comments},
15             async: true,
16             beforeSend:function(xhr, settings){
17                 xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
18             },
19             success: function(data) {
20                 if(data.status == 'fail'){
21                     if(data.msg == '用户未登录'){
22                         window.location.href="/login/";
23                     }else{
24                         alert(data.msg)
25                     }
26
27                 }else if(data.status == 'success'){
28                     window.location.reload();//刷新当前页面.
29                 }
30             },
31         });
32     });
33
34 </script>
35 {% endblock %}

  然后修改课程评论页面中显示评论信息的代码:

  现在就可以提交评论信息了,并且是异步提交,不会刷新页面。

3、课程与用户相关联

  在课程详情页面点击开始学习之后,应该将课程与用户关联起来。

  如果点击开始学习,需要验证用户是否是登录状态,如果没有登录需要让用户先登录,将验证登录这个功能写成一个类,哪个接口需要验证登录继承这个类即可。在utils目录下创建文件mixin_utils.py(将最基本的类都放在这个文件中):

 1 from django.utils.decorators import method_decorator
 2 from django.contrib.auth.decorators import login_required
 3
 4
 5 class LoginRequiredMixin(object):
 6     """验证登录基类"""
 7
 8     @method_decorator(login_required(login_url='/login/'))
 9     def dispatch(self, request, *args, **kwargs):
10         return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)

  然后让课程章节接口和课程评论接口都继承这个基类,继承之后,没有登录的用户点击开始学习,会跳转到登录页面:

 1 class CourseLessonView(LoginRequiredMixin, View):
 2     """课程章节"""
 3     def get(self, request, course_id):
 4         # 根据前端传递的课程id找到对应的课程
 5         course = Course.objects.get(id=int(course_id))
 6
 7         # 获取所有的资源文件
 8         all_resources = CourseResourse.objects.filter(course=course)
 9
10         # 相关课程推荐
11         # 找到学习这门课程的所有用户
12         user_courses = UserCourse.objects.filter(course=course)
13         # 找到学习这门课的所有用户的id
14         user_ids = [user_course.user_id for user_course in user_courses]
15         # 通过所有用户的id,找到所有用户学习过的所有课程
16         all_user_courses = UserCourse.objects.filter(user_id__in=user_ids)
17         # 取出所有课程id
18         course_ids = [all_user_course.course_id for all_user_course in all_user_courses]
19         # 通过所有课程id找到所有的课程,按点击量区5个
20         relate_courses = Course.objects.filter(id__in=course_ids).order_by('-click_nums')[:5]
21
22
23         return render(request, 'course-video.html', {
24             'course': course,
25             'all_resources': all_resources,
26             'relate_courses': relate_courses
27         })
28
29
30 class CourseCommentsView(LoginRequiredMixin, View):
31     """课程评论"""
32     def get(self, request, course_id):
33         course = Course.objects.get(id=int(course_id))
34         all_resources = CourseResourse.objects.filter(course=course)
35
36         # 获取所有的评论信息
37         all_comments = CourseComments.objects.all()
38
39         return render(request, 'course-comment.html', {
40             'course': course,
41             'all_resources': all_resources,
42             'all_comments': all_comments
43         })

View Code

  然后将用户和课程关联起来,完善课程章节接口:

 1 class CourseLessonView(LoginRequiredMixin, View):
 2     """课程章节"""
 3     def get(self, request, course_id):
 4         # 根据前端传递的课程id找到对应的课程
 5         course = Course.objects.get(id=int(course_id))
 6
 7         # 课程和用户关联,先判断用户是否已经学习过该课程
 8         user_courses = UserCourse.objects.filter(user=request.user, course=course)
 9         if not user_courses:
10             # 没有学习过该课程,关联
11             user_course = UserCourse(user=request.user, course=course)
12             user_course.save()
13
14         # 获取所有的资源文件
15         all_resources = CourseResourse.objects.filter(course=course)
16
17         # 相关课程推荐
18         # 找到学习这门课程的所有用户
19         user_courses = UserCourse.objects.filter(course=course)
20         # 找到学习这门课的所有用户的id
21         user_ids = [user_course.user_id for user_course in user_courses]
22         # 通过所有用户的id,找到所有用户学习过的所有课程
23         all_user_courses = UserCourse.objects.filter(user_id__in=user_ids)
24         # 取出所有课程id
25         course_ids = [all_user_course.course_id for all_user_course in all_user_courses]
26         # 通过所有课程id找到所有的课程,按点击量区5个
27         relate_courses = Course.objects.filter(id__in=course_ids).order_by('-click_nums')[:5]
28
29         return render(request, 'course-video.html', {
30             'course': course,
31             'all_resources': all_resources,
32             'relate_courses': relate_courses
33         })

  现在点击开始学习之后,在页面的右下角就有学过的其他课程了。

十三、视频播放功能

  视频播放器我们使用video.js,它是一款基于HTML5的网络视频播放器。它支持HTML5和Flash视频,以及YouTube和Vimeo(通过插件)。支持在桌面和移动设备上播放视频。

1、前端页面配置

  将视频播放页面course-play.html拷贝到templates目录下。

  继承base.html页面,重写需要block的地方:

  custom_css中的代码如下:

  然后下载video-js.min.css和video.min.js分别放到css和js目录下。

2、视频播放接口

 1 class VideoPlayView(LoginRequiredMixin, View):
 2     """视频播放"""
 3     def get(self, request, video_id):
 4         # 根据前端的视频id找到对应的视频
 5         video = Video.objects.get(id=int(video_id))
 6
 7         # 通过外键先找到章节在找到对应的课程,然后学习人数加1
 8         course = video.lesson.course
 9         course.students += 1
10         course.save()
11
12         # 查询用户是否已经学习了该课程,如果没有将课程和用户关联
13         user_courses = UserCourse.objects.filter(user=request.user, course=course)
14         if not user_courses:
15             user_course = UserCourse(user=request.user, course=course)
16             user_course.save()
17
18         # 相关课程推荐
19         user_courses = UserCourse.objects.filter(course=course)
20         user_ids = [user_course.user_id for user_course in user_courses]
21         all_user_courses = UserCourse.objects.filter(user_id__in=user_ids)
22         course_ids = [all_user_course.course_id for all_user_course in all_user_courses]
23         relate_courses = Course.objects.filter(id__in=course_ids).order_by('-click_nums')[:5]
24
25         # 获取所有资源文件
26         all_resources = CourseResourse.objects.filter(course=course)
27
28         return render(request, 'course-play.html', {
29             'course': course,
30             'all_resources': all_resources,
31             'relate_courses': relate_courses,
32             'video': video
33         })

  配置url:

1 from .views import VideoPlayView
2
3 urlpatterns = [
4     re_path('video/(?P<video_id>\d+)/', VideoPlayView.as_view(), name='video_play'),  # 视频播放
5 ]

  然后修改课程章节页面章节中跳转到视频页面的url:

  最后将视频播放页面中显示代码进行修改:

  1 {% extends 'base.html' %}
  2
  3 {% load staticfiles %}
  4
  5 {% block titile %}
  6     {{ video.name }} -- 知能网
  7 {% endblock %}
  8
  9 {% block custom_bread %}
 10     <section>
 11         <div class="wp">
 12             <div class="crumbs">
 13                 <ul>
 14                     <li><a href="{% url 'index' %}">首页</a>></li>
 15                     <li><a href="{% url 'course:course_list' %}">公开课程</a>></li>
 16                     <li><a href="{% url 'course:course_detail' course.id %}">{{ course.name }}</a>></li>
 17                     <li>{{ video.name }}</li>
 18                 </ul>
 19             </div>
 20         </div>
 21     </section>
 22 {% endblock %}
 23
 24 {% block custom_css %}
 25     <link rel="stylesheet" type="text/css" href="{% static 'css/video-js.min.css' %}">
 26     <link rel="stylesheet" type="text/css" href="{% static 'css/muke/base.css' %}"/>
 27     <link rel="stylesheet" type="text/css" href="{% static 'css/muke/common-less.css' %}"/>
 28     <link rel="stylesheet" type="text/css" href="{% static 'css/muke/course/learn-less.css' %}"/>
 29     <link rel="stylesheet" type="text/css" href="{% static 'css/mooc.css' %}"/>
 30     <link rel="stylesheet" type="text/css" href="{% static 'css/muke/course/common-less.css' %}">
 31     <style>
 32         .video-js .vjs-big-play-button { 33             top: 50%;
 34             left: 50%;
 35         }
 36     </style>
 37 {% endblock %}
 38
 39 {% block custom_js %}
 40     <script src="{% static 'js/video.min.js' %}" type="text/javascript"></script>
 41 {% endblock %}
 42
 43 {% block content %}
 44     <div id="main">
 45 {#    video.js视频播放器#}
 46         <div style="width:1200px;height: 650px; margin-left:100px">
 47                 <video id="example_video_1" class="video-js vjs-default-skin" controls preload="none" width="1200"
 48                        poster="http://video-js.zencoder.com/oceans-clip.png"
 49                        data-setup="{}" >
 50                     <source src="{{ video.url }}" type="video/mp4">
 51                 </video>
 52         </div>
 53
 54         <div class="course-info-main clearfix w has-progress">
 55             <div class="info-bar clearfix">
 56                 <div class="content-wrap clearfix">
 57                     <div class="content">
 58                         <div class="mod-tab-menu">
 59                             <ul class="course-menu clearfix">
 60                                 <li><a class="ui-tabs-active active" id="learnOn"
 61                                        href="{% url 'course:course_lesson' course.id %}"><span>章节</span></a></li>
 62                                 <li><a id="commentOn" class=""
 63                                        href="{% url 'course:course_comment' course.id %}"><span>评论</span></a></li>
 64                             </ul>
 65                         </div>
 66                         <div id="notice" class="clearfix">
 67                             <div class="l"><strong>课程公告:</strong> <a
 68                                     href="javascript:void(0)">Spring的文档以及相关的jar文件已上传</a></div>
 69                         </div>
 70
 71                         <div class="mod-chapters">
 72                             {% for lesson in course.lesson_set.get_queryset %}
 73                                 <div class="chapter chapter-active">
 74                                     <h3>
 75                                         <strong><i class="state-expand"></i>{{ lesson.name }}</strong>
 76                                     </h3>
 77                                     <ul class="video">
 78
 79                                         {% for video in lesson.video_set.get_queryset %}
 80                                             <li>
 81                                                 <a target="_blank" href='{% url 'course:video_play' video.id %}'
 82                                                    class="J-media-item studyvideo">{{ video.name }}
 83                                                     ({{ video.learn_times }})
 84                                                     <i class="study-state"></i>
 85                                                 </a>
 86                                             </li>
 87                                         {% endfor %}
 88
 89                                     </ul>
 90                                 </div>
 91                             {% endfor %}
 92                         </div>
 93
 94                     </div>
 95                     <div class="aside r">
 96                         <div class="bd">
 97
 98                             <div class="box mb40">
 99                                 <h4>资料下载</h4>
100                                 <ul class="downlist">
101                                     {% for course_resource in course.courseresource_set.get_queryset %}
102                                         <li>
103                                             <span><i
104                                                     class="aui-iconfont aui-icon-file"></i>&nbsp;&nbsp;{{ course_resource.name }}</span>
105                                             <a href="{{ MEDIA_URL }}{{ course_resource.download }}" class="downcode"
106                                                target="_blank" download="" data-id="274" title="">下载</a>
107                                         </li>
108                                     {% endfor %}
109                                 </ul>
110                             </div>
111                             <div class="box mb40">
112                                 <h4>讲师提示</h4>
113                                 <div class="teacher-info">
114                                     <a href="{% url 'org:org_teacher' course.teacher.id %}" target="_blank">
115                                         <img src='{{ MEDIA_URL }}{{ course.teacher.image }}' width='80' height='80'/>
116                                     </a>
117                                     <span class="tit">
118           <a href="{% url 'org:org_teacher' course.teacher.id %}" target="_blank">{{ course.teacher.name }}</a>
119         </span>
120                                     <span class="job">{{ course.teacher.work_position }}</span>
121                                 </div>
122                                 <div class="course-info-tip">
123                                     <dl class="first">
124                                         <dt>课程须知</dt>
125                                         <dd class="autowrap">{{ course.you_need_know }}</dd>
126                                     </dl>
127                                     <dl>
128                                         <dt>老师告诉你能学到什么?</dt>
129                                         <dd class="autowrap">{{ course.teacher_tell }}</dd>
130                                     </dl>
131                                 </div>
132                             </div>
133
134
135                             <div class="cp-other-learned  js-comp-tabs">
136                                 <div class="cp-header clearfix">
137                                     <h2 class="cp-tit l">该课的同学还学过</h2>
138                                 </div>
139                                 <div class="cp-body">
140                                     <div class="cp-tab-pannel js-comp-tab-pannel" data-pannel="course"
141                                          style="display: block">
142                                         <!-- img 200 x 112 -->
143                                         <ul class="other-list">
144
145                                             {% for relate_course in relate_courses %}
146                                                 <li class="curr">
147                                                     <a href="{% url 'course:course_detail' relate_course.id %}"
148                                                        target="_blank">
149                                                         <img src="{{ MEDIA_URL }}{{ relate_course.image }}"
150                                                              alt="{{ relate_course.name }}">
151                                                         <span class="name autowrap">{{ relate_course.name }}</span>
152                                                     </a>
153                                                 </li>
154                                             {% endfor %}
155
156                                         </ul>
157                                     </div>
158                                     <div class="cp-tab-pannel js-comp-tab-pannel" data-pannel="plan">
159                                         <ul class="other-list">
160
161                                         </ul>
162                                     </div>
163                                 </div>
164                             </div>
165
166                         </div>
167                     </div>
168                 </div>
169                 <div class="clear"></div>
170
171             </div>
172
173         </div>
174     </div>
175 {% endblock %}

View Code

转载于:https://www.cnblogs.com/Sweltering/p/9979810.html

(项目)在线教育平台(九)相关推荐

  1. 数仓项目——在线教育平台离线数据仓库效果展示

    背景:基于阿里云的3台ECS云服务器搭建了在线教育平台的离线数据仓库,本文仅用于记录最终的效果,从0到1的实现过程后续进行补充,由于抢占式实例的云服务器按量进行每小时计费,为了避免持续的收费,所以我急 ...

  2. 第三百九十二节,Django+Xadmin打造上线标准的在线教育平台—sql注入攻击,xss攻击,csrf攻击...

    第三百九十二节,Django+Xadmin打造上线标准的在线教育平台-sql注入攻击,xss攻击,csrf攻击 sql注入攻击 也就是黑客通过表单提交的地方,在表单里输入了sql语句,就是通过SQL语 ...

  3. 第三百八十九节,Django+Xadmin打造上线标准的在线教育平台—列表筛选结合分页...

    第三百八十九节,Django+Xadmin打造上线标准的在线教育平台-列表筛选结合分页 根据用户的筛选条件来结合分页 实现原理就是,当用户点击一个筛选条件时,通过get请求方式传参将筛选的id或者值, ...

  4. 第三百九十一节,Django+Xadmin打造上线标准的在线教育平台—404,403,500页面配置...

    第三百九十一节,Django+Xadmin打造上线标准的在线教育平台-404,403,500页面配置 路由映射 在全局也就是根目录里的urls.py里配置404路由映射 注意:不是写在urlpatte ...

  5. 基于SpringBoot+Vue前后端分离的在线教育平台项目

    基于SpringBoot+Vue前后端分离的在线教育平台项目 赠给有缘人,希望能帮助到你!也请不要吝惜你的大拇指,你的Star.点赞将是对我最大的鼓励与支持! 开源传送门: 后台:Gitee | Gi ...

  6. 在线教育平台项目——需求分析

    Hello,我是 Alex 007,一个热爱计算机编程和硬件设计的小白,为啥是007呢?因为叫 Alex 的人太多了,再加上每天007的生活,Alex 007就诞生了. 有一段时间没好好写文章了,可不 ...

  7. 【项目】在线教育平台项目总结

    1.项目总体描述 在线教育平台采用了B2C商业模块,基于微服务架构,采用前后端分离的方式进行开发 2.功能模块 基于前后台的模式开发,前台系统是给使用这个平台进行学习的用户,后台系统是给管理员使用的 ...

  8. 在线教育平台项目——整体架构

    Hello,我是 Alex 007,一个热爱计算机编程和硬件设计的小白,为啥是007呢?因为叫 Alex 的人太多了,再加上每天007的生活,Alex 007就诞生了. 有一段时间没好好写文章了,可不 ...

  9. Django项目于之在线教育平台网站的实战开发(三)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :Django项目于之在线教育平台网站的实战开发(二)_cdtaogang's blog-CSDN博客 ...

  10. Django+xadmin打造在线教育平台(十)

    目录 在线教育平台(一)      在线教育平台(二) 在线教育平台(三)      在线教育平台(四) 在线教育平台(五)      在线教育平台(六) 在线教育平台(七)      在线教育平台( ...

最新文章

  1. 移动端1px像素的设置?
  2. 用Python做垃圾分类
  3. NoSQL-MongoDB with python
  4. C#4.0 命名参数可选参数
  5. JavaScript:执行上下文执行上下文栈
  6. Android Studio如何查找和替换
  7. 用vue-cli+iview做项目不兼容ie问题
  8. 使用DirectPlay进行网络互联(1)
  9. php dht爬虫,利用DHT网络,爬取bt种子。
  10. 微型计算机8086工作原理,8086到80486微型计算机系统原理与接口
  11. One afternoon in Zhongguancun(redo CC5)
  12. 美国零售业初创公司排名前5位的软件开发公司
  13. 论文阅读笔记《Learning for Disparity Estimation through Feature Constancy》
  14. iOS 可用的热更新、热修复方案
  15. HTML 视频(Videos)播放
  16. R语言广义线性模型函数GLM、glm函数构建泊松回归模型(Poisson regression)、泊松回归模型系数解读、查看系数的乘法效应(Interpreting the model para)
  17. python变量名必须以字母或下划线开头不区分字母大小写_Python变量名必须以字符或下划线开头,并且区分字母大小写。...
  18. 初级SQL开发汇总指南
  19. Android系统启动流程 -- bootloader
  20. c语言编写消防车声音程序教程,51单片机蜂鸣器模拟救护车消防车等各种报警喇叭声音的学习源代码...

热门文章

  1. 5-5 圆周率Java
  2. 修改注册表,更改Win10版本,解决升级时无法“保留个人文件和应用”的问题
  3. 《国庆中秋除了发月饼,企业更应该做什么?》
  4. 玩转html5(一)-----盘点html5新增的那些酷酷的input类型和属性
  5. java是编译型语言还是解释型语言?
  6. 版本管理之SVN实践教程:基础篇(5):提交/解决冲突/回退/确认
  7. golang中的rune类型
  8. OCR图片预处理之去除印章(一)
  9. 【uiautomation】批量给微信好友/群聊发消息
  10. 诺基亚C5智能手机的功能非常好,并具有一定程度的可取性