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