十、课程详情页功能
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代码:
然后修改课程详情页面课程收藏,机构收藏的代码: