十、课程详情页功能
1、课程列表页面
1.1 前端页面配置
将前端页面course-list.html放到templates目录下,
课程相关的页面大致和base.html页面的机构一致,继承这个页面即可,重写block部分:
1.2 课程列表接口
在course/views.py文件中编写课程相关的接口:
1 from django.views.generic import View
2
3 # Create your views here.
4
5 class CourseListView(View):
6 """课程列表页"""
7 def get(self, request):
8 return render(request, 'course-list.html')
首先在MxOnline/urls.py配置课程的一级路由:
1 urlpatterns = [
2 path('course/', include('course.urls', namespace='course')), # 课程
3 ]
然后在course下新建urls.py文件,添加课程列表的路由:
1 from django.urls import path
2
3 from .views import CourseListView
4
5
6 app_name = 'course'
7
8 urlpatterns = [
9 path('list/', CourseListView.as_view(), name='course_list'), # 课程列表
10 ]
现在在index.html页面修改跳转到公开课页面(课程列表页)的url:
在首页点击公开课即可跳转到课程列表页。
完善课程列表接口:
1 class CourseListView(View):
2 """课程列表页"""
3 def get(self, request):
4 # 获取所有的课程
5 all_courses = Course.objects.all()
6
7 return render(request, 'course-list.html', {
8 'all_courses': all_courses
9 })
修改课程列表页面的前端显示代码:
1.3 分页功能
在课程列表接口中完善分页逻辑:
1 class CourseListView(View):
2 """课程列表页"""
3 def get(self, request):
4 # 获取所有的课程
5 all_courses = Course.objects.all()
6
7 # 分页
8 try:
9 page = request.GET.get('page', 1)
10 except PageNotAnInteger:
11 page = 1
12 p = Paginator(all_courses, 3, request=request)
13 courses = p.page(page)
14
15 return render(request, 'course-list.html', {
16 'all_courses': courses
17 })
修改课程列表页面的分页代码,在这之前在课程迭代显示的代码上需要加上object_list:
1.4 排序功能
在课程列表接口中完善排序的逻辑(根据学习人数和点击数排序):
1 class CourseListView(View):
2 """课程列表页"""
3 def get(self, request):
4 # 获取所有的课程
5 all_courses = Course.objects.all()
6
7 # 排序(学习人数,点击数)
8 sort = request.GET.get('sort', '')
9 if sort:
10 if sort == 'students':
11 all_courses = all_courses.order_by('-students')
12 elif sort == 'hot':
13 all_courses = all_courses.order_by('-click_nums')
14
15 # 分页
16 try:
17 page = request.GET.get('page', 1)
18 except PageNotAnInteger:
19 page = 1
20 p = Paginator(all_courses, 3, request=request)
21 courses = p.page(page)
22
23 return render(request, 'course-list.html', {
24 'all_courses': courses,
25 'sort': sort
26 })
然后修改前端排序选项选中效果的代码:
1.5 热门课程推荐功能
在课程列表接口中完善热门课程推荐逻辑:
1 class CourseListView(View):
2 """课程列表页"""
3 def get(self, request):
4 # 获取所有的课程
5 all_courses = Course.objects.all()
6
7 # 排序(学习人数,点击数)
8 sort = request.GET.get('sort', '')
9 if sort:
10 if sort == 'students':
11 all_courses = all_courses.order_by('-students')
12 elif sort == 'hot':
13 all_courses = all_courses.order_by('-click_nums')
14
15 # 热门课程
16 hot_courses = all_courses.order_by('-click_nums')[:2]
17
18 # 分页
19 try:
20 page = request.GET.get('page', 1)
21 except PageNotAnInteger:
22 page = 1
23 p = Paginator(all_courses, 3, request=request)
24 courses = p.page(page)
25
26 return render(request, 'course-list.html', {
27 'all_courses': courses,
28 'sort': sort,
29 'hot_courses': hot_courses
30 })
修改课程列表页面热门课程推荐显示的代码:
2、课程详情页面
2.1 前端页面配置
将前端页面course-detail.html放到templates目录下,
继承base.html页面,重写block部分:
2.2 课程详情接口
1 class CourseDetailView(View):
2 """课程详情"""
3 def get(self, request, course_id):
4 return render(request, 'course-detail.html')
配置url:
1 from .views import CourseDetailView
2
3 urlpatterns = [
4 re_path('course/(?P<course_id>\d+)/', CourseDetailView.as_view(), name='course_detail'), # 课程详情
5 ]
修改课程列表页中点击课程进入课程详情页面的url:
现在点击课程之后,就可以进入课程详情页面。
前端显示需要有课程类别,章节数和学习这门课程的用户信息,需要在课程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 add_time = models.DateTimeField('添加时间', default=datetime.now)
21
22 class Meta:
23 verbose_name = '课程'
24 verbose_name_plural = verbose_name
25
26 # 获取章节数
27 def get_zj_nums(self):
28 return self.lesson_set.all().count()
29
30 # 获取学习用户
31 def get_learn_users(self):
32 return self.usercourse_set.all()[:5]
33
34 def __str__(self):
35 return self.name
迁移数据库。
完善课程详情接口:
1 class CourseDetailView(View):
2 """课程详情"""
3 def get(self, request, course_id):
4 # 根据前端的课程id获取该课程
5 course = Course.objects.get(id=int(course_id))
6
7 # 只要点击该课程,点击数就加1
8 course.click_nums += 1
9 course.save()
10
11 return render(request, 'course-detail.html', {
12 'course': course
13 })
修改课程详情页面数据显示的代码:
刷新页面,可以看到这个课程的详细信息。
右侧授课机构要显示机构教师的数量,所以需要在机构的model中添加一个获取教师数量的函数:
1 class CourseOrg(models.Model):
2 """课程机构"""
3 CATEGORY_CHOICES = (
4 ('pxjg', '培训机构'),
5 ('gx', '高校'),
6 ('gr', '个人')
7 )
8 name = models.CharField('机构名称', max_length=50)
9 category = models.CharField('机构类别', max_length=20, choices=CATEGORY_CHOICES, default='pxjg')
10 desc = models.TextField('机构描述')
11 students = models.IntegerField('学习人数', default=0)
12 course_nums = models.IntegerField('课程数', default=0)
13 click_nums = models.IntegerField('点击数', default=0)
14 fav_nums = models.IntegerField('收藏数', default=0)
15 image = models.ImageField('封面图', upload_to='org/%Y/%m', max_length=100)
16 address = models.CharField('地址', max_length=150)
17 city = models.ForeignKey(CityDict, verbose_name='所在城市', on_delete=models.CASCADE)
18 add_time = models.DateTimeField('添加时间', default=datetime.now)
19
20 class Meta:
21 verbose_name = '课程机构'
22 verbose_name_plural = verbose_name
23
24 # 获取教师数量
25 def get_teacher_nums(self):
26 return self.teacher_set.all().count()
27
28 def __str__(self):
29 return self.name
修改课程详情页面右侧机构的显示代码:
右侧相关课程推荐,那么如何判断推荐的课程呢,需要给课程添加一个tag字段,如果该字段相同,那就推荐相同的tag的课程即可,在课程的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 def __str__(self):
36 return self.name
然后在课程详情接口中添加课程推荐的逻辑:
1 class CourseDetailView(View):
2 """课程详情"""
3 def get(self, request, course_id):
4 # 根据前端的课程id获取该课程
5 course = Course.objects.get(id=int(course_id))
6
7 # 只要点击该课程,点击数就加1
8 course.click_nums += 1
9 course.save()
10
11 # 课程推荐,根据tag判断
12 tag = course.tag
13 if tag:
14 relate_courses = Course.objects.filter(tag=tag)[1:3]
15 else:
16 relate_courses = []
17
18 return render(request, 'course-detail.html', {
19 'course': course,
20 'relate_courses': relate_courses
21 })
修改课程详情页面右侧推荐课程显示的代码:
2.3 课程和机构收藏功能
在课程详情接口中添加收藏的逻辑:
1 class CourseDetailView(View):
2 """课程详情"""
3 def get(self, request, course_id):
4 # 根据前端的课程id获取该课程
5 course = Course.objects.get(id=int(course_id))
6
7 # 只要点击该课程,点击数就加1
8 course.click_nums += 1
9 course.save()
10
11 # 课程推荐,根据tag判断
12 tag = course.tag
13 if tag:
14 relate_courses = Course.objects.filter(tag=tag)[1:3]
15 else:
16 relate_courses = []
17
18 # 课程收藏,机构收藏
19 has_fav_course = False
20 has_fav_org = False
21 # 未登录由前端跳转到登录页面
22 if request.user.is_authenticated:
23 if UserFavorite.objects.filter(user=request.user, fav_id=course.id, fav_type=1):
24 has_fav_course = True
25 if UserFavorite.objects.filter(user=request.user, fav_id=course.course_org.id, fav_type=2):
26 has_fav_org = True
27
28 return render(request, 'course-detail.html', {
29 'course': course,
30 'relate_courses': relate_courses,
31 'has_fav_course': has_fav_course,
32 'has_fav_org': has_fav_org
33 })
将base.html页面中的{% block custom_js %}{% endblock %},放到最下面的位置,因为是js代码,要最后加载,然后在课程详情页面中重写ajax的js代码:
然后修改课程详情页面课程收藏,机构收藏的代码: