十四、授课教师功能
1、讲师列表页面
1.1 前端页面配置
将讲师列表页面teachers-list.html拷贝到templates下。
继承base页面,重写需要block的地方:
1.2 讲师列表接口
在organization/views.py中编写讲师列表的接口:
1 class TeacherListView(View): 2 """讲师列表""" 3 def get(self, request): 4 # 获取所有的讲师 5 all_teachers = Teacher.objects.all() 6 7 return render(request, 'teachers-list.html', { 8 'all_teachers': all_teachers 9 })
配置url:
from .views import TeacherListView urlpatterns = [ re_path('teacher/list/', TeacherListView.as_view(), name='teacher_list'), # 讲师列表 ]
修改index.html中跳转到讲师列表页面的url:
在讲师列表页面需要显示讲师的年龄,需要在teacher的model中增加一个年龄的字段:
1 class Teacher(models.Model): 2 """机构老师""" 3 org = models.ForeignKey(CourseOrg, verbose_name='所属机构', on_delete=models.CASCADE) 4 name = models.CharField('老师名', max_length=50) 5 age = models.IntegerField('年龄', default=25) 6 work_years =models.IntegerField('工作年限', default=0) 7 work_company = models.CharField('就职公司', max_length=50) 8 work_position = models.CharField('工作职位', max_length=50) 9 points = models.CharField('教学特点', max_length=50) 10 click_nums = models.IntegerField('点击数', default=0) 11 fav_nums = models.IntegerField('收藏数', default=0) 12 image = models.ImageField('头像', upload_to='teacher/%Y/%m', max_length=100, default='') 13 add_time = models.DateTimeField('添加时间', default=datetime.now) 14 15 class Meta: 16 verbose_name = '教师' 17 verbose_name_plural = verbose_name 18 19 def __str__(self): 20 return '[{}]机构的教师:{}'.format(self.org.name, self.name)
迁移数据库。
然后修改讲师列表页面显示讲师信息的代码:
1.3 分页功能
在讲师列表接口中完善分页的逻辑:
1 class TeacherListView(View): 2 """讲师列表""" 3 def get(self, request): 4 # 获取所有的讲师 5 all_teachers = Teacher.objects.all() 6 7 # 统计讲师的总数 8 teacher_nums = all_teachers.count() 9 10 # 分页 11 try: 12 page = request.GET.get('page', 1) 13 except PageNotAnInteger: 14 page = 1 15 p = Paginator(all_teachers, 5, request=request) 16 teachers = p.page(page) 17 18 return render(request, 'teachers-list.html', { 19 'all_teachers': teachers, 20 'teacher_nums': teacher_nums 21 })
在遍历讲师的时候需要加上object_list属性,否则在分页会抛出异常:
修改前端分页显示的代码:
1.4 排序功能
讲师可以根据人气进行排序,完善讲师列表接口中排序的逻辑:
1 class TeacherListView(View): 2 """讲师列表""" 3 def get(self, request): 4 # 获取所有的讲师 5 all_teachers = Teacher.objects.all() 6 7 # 统计讲师的总数 8 teacher_nums = all_teachers.count() 9 10 # 排序,按点击数排序 11 sort = request.GET.get('sort', '') 12 if sort: 13 if sort == 'hot': 14 all_teachers = all_teachers.order_by('-click_nums') 15 16 # 分页 17 try: 18 page = request.GET.get('page', 1) 19 except PageNotAnInteger: 20 page = 1 21 p = Paginator(all_teachers, 5, request=request) 22 teachers = p.page(page) 23 24 return render(request, 'teachers-list.html', { 25 'all_teachers': teachers, 26 'teacher_nums': teacher_nums, 27 'sort': sort 28 })
修改讲师列表页面中按人气选中的状态显示代码:
在讲师列表页面右侧有讲师排行版,完善讲师列表接口中排行榜的逻辑:
1 class TeacherListView(View): 2 """讲师列表""" 3 def get(self, request): 4 # 获取所有的讲师 5 all_teachers = Teacher.objects.all() 6 7 # 统计讲师的总数 8 teacher_nums = all_teachers.count() 9 10 # 排序,按点击数排序 11 sort = request.GET.get('sort', '') 12 if sort: 13 if sort == 'hot': 14 all_teachers = all_teachers.order_by('-click_nums') 15 16 # 讲师排行版 17 teacher_sorted = all_teachers.order_by('-click_nums')[:3] 18 19 # 分页 20 try: 21 page = request.GET.get('page', 1) 22 except PageNotAnInteger: 23 page = 1 24 p = Paginator(all_teachers, 5, request=request) 25 teachers = p.page(page) 26 27 return render(request, 'teachers-list.html', { 28 'all_teachers': teachers, 29 'teacher_nums': teacher_nums, 30 'sort': sort, 31 'teacher_sorted': teacher_sorted 32 })
修改讲师列表页面中显示讲师排行榜的代码:
2、讲师详情页面
2.1 前端页面配置
将讲师详情页面teacher-detail.html拷贝到templates下。
继承base页面,重写需要block的地方:
2.2 讲师详情接口
1 class TeacherDetailView(View): 2 """讲师详情页面""" 3 def get(self, request, teacher_id): 4 # 根据前端的讲师id找到对应的讲师 5 teacher = Teacher.objects.get(id=int(teacher_id)) 6 7 # 获取该老师所有的课程 8 all_courses = Course.objects.filter(teacher=teacher) 9 10 # 讲师排行 11 teacher_sorted = Teacher.objects.all().order_by('-click_nums')[:3] 12 13 return render(request, 'teacher-detail.html', { 14 'teacher': teacher, 15 'all_courses': all_courses, 16 'teacher_sorted': teacher_sorted 17 })
配置url:
1 from .views import TeacherDetailView 2 3 urlpatterns = [ 4 re_path('teacher/detail/(?P<teacher_id>d+)/', TeacherDetailView.as_view(), name='teacher_detail'), # 讲师详情 5 ]
在讲师列表页面修改点击讲师跳转到讲师详情页面的url:
修改讲师详情页面信息的显示代码:
2.3 收藏
在讲师详情页面可以收藏讲师,右侧可以收藏机构,完善讲师详情接口中收藏的判断逻辑:
1 class TeacherDetailView(View): 2 """讲师详情页面""" 3 def get(self, request, teacher_id): 4 # 根据前端的讲师id找到对应的讲师 5 teacher = Teacher.objects.get(id=int(teacher_id)) 6 7 # 获取该老师所有的课程 8 all_courses = Course.objects.filter(teacher=teacher) 9 10 # 讲师排行 11 teacher_sorted = Teacher.objects.all().order_by('-click_nums')[:3] 12 13 # 讲师收藏、机构收藏 14 has_teahcer_faved = False 15 if UserFavorite.objects.filter(user=request.user, fav_type=3, fav_id=teacher_id): 16 has_teahcer_faved = True 17 has_org_faved = False 18 if UserFavorite.objects.filter(user=request.user, fav_type=2, fav_id=teacher.org.id): 19 has_org_faved = True 20 21 return render(request, 'teacher-detail.html', { 22 'teacher': teacher, 23 'all_courses': all_courses, 24 'teacher_sorted': teacher_sorted, 25 'has_teahcer_faved': has_teahcer_faved, 26 'has_org_faved': has_org_faved 27 })
修改讲师详情页面中收藏的判断代码:
因为收藏操作是由前端通过ajax异步操作的,需要在讲师详情页面的最下面加上script代码:
1 {% block custom_js %} 2 <script type="text/javascript"> 3 //收藏分享 4 function add_fav(current_elem, fav_id, fav_type){ 5 $.ajax({ 6 cache: false, 7 type: "POST", 8 url:"{% url "org:add_fav" %}", 9 data:{'fav_id':fav_id, 'fav_type':fav_type}, 10 async: true, 11 beforeSend:function(xhr, settings){ 12 xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}"); 13 }, 14 success: function(data) { 15 if(data.status == 'fail'){ 16 if(data.msg == '用户未登录'){ 17 window.location.href="/login/"; 18 }else{ 19 alert(data.msg) 20 } 21 22 }else if(data.status == 'success'){ 23 current_elem.text(data.msg) 24 } 25 }, 26 }); 27 } 28 29 $('#jsLeftBtn').on('click', function(){ 30 add_fav($(this), {{ teacher.id }}, 3); 31 }); 32 33 $('#jsRightBtn').on('click', function(){ 34 add_fav($(this), {{ teacher.org.id }}, 2); 35 }); 36 </script> 37 {% endblock %}