class HomeworkHandler(PermissionHandler, StartXHandler): def display_outline(self, model=None, is_header=None, *args, **kwargs): if is_header: return '作业详情' record_url = reverse('startX:generic_homeworkdetail_list', kwargs={'homework_id': model.pk}) return mark_safe('<a target="_blank" href="%s">作业详情</a>' % record_url) list_display = [ get_m2m_display('课程', 'courses'), 'title', get_m2m_display('章节', 'chapter'), 'content', display_outline ] search_list = ['courses__contains']
class ClassesHandler(PermissionHandler, StartXHandler): model_form_class = ClassesModelForm def display_course(self, model=None, is_header=None, *args, **kwargs): if is_header: return '班级' return '%s(%s期)' % (model.course.name, model.semester) def display_classes_record(self, model=None, is_header=None, *args, **kwargs): if is_header: return '上课记录' record_url = reverse('startX:generic_courserecord_list', kwargs={'class_id': model.pk}) return mark_safe('<a target="_blank" href="%s">上课记录</a>' % record_url) list_display = [ 'school', display_course, get_datetime_format('开班日期', 'start_date'), 'class_teacher', display_classes_record, get_m2m_display('任课老师', 'tech_teachers'), 'price' ] search_list = [ 'course__contains', 'semester__contains', 'school__contains' ] search_group = [ Option('school'), Option('course'), ]
class StudyRecordHandler(PermissionHandler, StartXHandler): def get_urls(self): """预留的重新自定义url钩子函数,主要是覆盖掉默认的url,并设置name别名""" patterns = [ re_path(r'^list/(?P<student_id>\d+)/$', self.wrapper(self.changelist), name=self.get_list_name), re_path(r'^add/(?P<student_id>\d+)/$', self.wrapper(self.add_view), name=self.get_add_name), re_path(r'^change/(?P<student_id>\d+)/(?P<pk>\d+)/$', self.wrapper(self.change_view), name=self.get_change_name), ] patterns.extend(self.extra_url()) return patterns def display_edit(self, model=None, is_header=None, *args, **kwargs): if is_header: return '操作' student_id = kwargs.get('student_id') tpl = '<a href="%s">编辑</a> ' % self.reverse_change_url( pk=model.pk, student_id=student_id) return mark_safe(tpl) def get_list_display(self, request, *args, **kwargs): """ 预留的钩子函数 :return: 为不同权限的用户设置预留的扩展,自定义显示列 """ value = [] if self.list_display: value.extend(self.list_display) value.append(type(self).display_edit) return value list_display = [ get_m2m_display('课时', 'course_lesson'), get_m2m_display('学生', 'student'), get_field_display('状态', 'status'), ]
class PrivateCustomerHandler(PermissionHandler, StartXHandler): """ 私户设置 """ def display_record(self, model=None, is_header=None, *args, **kwargs): if is_header: return '跟进记录' record_url = reverse('startX:generic_consultrecord_list', kwargs={'customer_id': model.pk}) return mark_safe('<a target="_blank" href="%s">跟进记录</a>' % record_url) def display_pay_record(self, model=None, is_header=None, *args, **kwargs): if is_header: return '缴费' record_url = reverse('startX:generic_paymentrecord_list', kwargs={'customer_id': model.pk}) return mark_safe('<a target="_blank" href="%s">缴费记录</a>' % record_url) def get_model_queryset(self, request, *args, **kwargs): current_consultant_id = request.session['staffinfo']['staff_id'] return self.model_class.objects.filter(consultant_id=current_consultant_id) def action_multi_remove(self, request, *args, **kwargs): """ 批量将私户客户拉取到公户 :return: """ pk_list = request.POST.getlist('pk') current_consultant_id = request.session['staffinfo']['staff_id'] self.model_class.objects.filter(consultant_id=current_consultant_id, id__in=pk_list).update(consultant=None) action_multi_remove.text = "移除到公户" def save(self, request, form, is_update, *args, **kwargs): """ 添加数据时,重写save方法,直接保存到当前用户的私户里 :param request: :param form: :param is_update: :param args: :param kwargs: :return: """ if not is_update: current_consultant_id = request.session['staffinfo']['staff_id'] form.instance.consultant_id = current_consultant_id form.save() action_list = [action_multi_remove, ] model_form_class = PrivateModelForm list_display = [StartXHandler.display_checkbox, 'name', 'qq', get_field_display('报名状态', 'status'), get_m2m_display('咨询课程', 'course'), display_record, display_pay_record]
class StudentHandler(PermissionHandler, StartXHandler): def display_score(self, model=None, is_header=None, *args, **kwargs): if is_header: return '积分管理' record_url = reverse('startX:generic_scorerecord_list', kwargs={'student_id': model.pk}) return mark_safe('<a target="_blank" href="%s">%s</a>' % (record_url, model.score)) list_display = [ 'customer', 'qq', 'mobile', 'emergency_contract', get_m2m_display('所报班级', 'classes'), display_score, get_field_display('学员状态', 'student_status'), 'memo' ] def get_add_btn(self, request, *args, **kwargs): return def get_list_display(self, request, *args, **kwargs): """ 预留的钩子函数 :return: 为不同权限的用户设置预留的扩展,自定义显示列 """ value = [] if self.list_display: value.extend(self.list_display) value.append(type(self).display_edit) return value def get_urls(self): """预留的重新自定义url钩子函数,主要是覆盖掉默认的url,并设置name别名""" patterns = [ re_path(r'^list/$', self.wrapper(self.changelist), name=self.get_list_name), re_path(r'^change/(?P<pk>\d+)/$', self.wrapper(self.change_view), name=self.get_change_name), ] patterns.extend(self.extra_url()) return patterns search_list = [ 'customer__name__contains', 'qq__contains', 'mobile__contains', ] search_group = [ Option('classes', text_func=lambda x: '%s-%s' % (x.school.title, str(x))) ]
class CourseDetailHandler(PermissionHandler, StartXHandler): def display_outline(self, model=None, is_header=None, *args, **kwargs): if is_header: return '课程大纲' record_url = reverse('startX:generic_courseoutline_list', kwargs={'course_id': model.pk}) return mark_safe('<a target="_blank" href="%s">课程大纲</a>' % record_url) def display_chapter(self, model=None, is_header=None, *args, **kwargs): if is_header: return '课程章节' record_url = reverse('startX:generic_coursechapter_list', kwargs={'course_id': model.pk}) return mark_safe('<a target="_blank" href="%s">课程章节</a>' % record_url) def display_coupon(self, model=None, is_header=None, *args, **kwargs): if is_header: return '课程优惠券' record_url = reverse('startX:generic_coupon_list', kwargs={'course_id': model.pk}) return mark_safe('<a target="_blank" href="%s">课程优惠券</a>' % record_url) def display_price_policy(self, model=None, is_header=None, *args, **kwargs): if is_header: return '价格策略' record_url = reverse('startX:generic_pricepolicy_list', kwargs={'course_id': model.pk}) return mark_safe('<a target="_blank" href="%s">价格策略</a>' % record_url) list_display = [ 'course', 'brief', get_m2m_display('课程', 'teacher'), display_outline, display_chapter, display_coupon, display_price_policy ] # 常见问题 search_list = ['course__contains'] search_group = [ Option('course'), Option('teacher'), ]
class StudentHandler(PermissionHandler, StartXHandler): order_by = ['id'] model_form_class = StudentModelForm def get_add_btn(self, request, *args, **kwargs): return None def get_urls(self): """预留的重新自定义url钩子函数,主要是覆盖掉默认的url,并设置name别名""" patterns = [ re_path(r'^list/$', self.wrapper(self.changelist), name=self.get_list_name), re_path(r'^change/(?P<pk>\d+)/$', self.wrapper(self.change_view), name=self.get_change_name), ] patterns.extend(self.extra_url()) return patterns def display_study_record(self, model=None, is_header=None, *args, **kwargs): if is_header: return '学习进度记录' record_url = reverse('startX:generic_studyrecord_list', kwargs={'student_id': model.pk}) return mark_safe('<a target="_blank" href="%s">学习进度记录</a>' % record_url) def display_consult_record(self, model=None, is_header=None, *args, **kwargs): if is_header: return '跟进记录' record_url = reverse('startX:generic_consultrecord_list', kwargs={'student_id': model.pk}) return mark_safe('<a target="_blank" href="%s">跟进记录</a>' % record_url) def get_list_display(self, request, *args, **kwargs): """ 预留的钩子函数 :return: 为不同权限的用户设置预留的扩展,自定义显示列 """ value = [] if self.list_display: value.extend(self.list_display) value.append(type(self).display_edit) return value list_display = [ 'account', 'qq', 'mobile', 'emergency_contract', 'score', get_field_display('状态', 'student_status'), get_m2m_display('已买课程', 'courses'), 'tutor', display_consult_record, display_study_record ]
class HomeworkDetailHandler(PermissionHandler, StartXHandler): model_form_class = HomeworkDetailModelForm def get_urls(self): """预留的重新自定义url钩子函数,主要是覆盖掉默认的url,并设置name别名""" patterns = [ re_path(r'^list/(?P<homework_id>\d+)/$', self.wrapper(self.changelist), name=self.get_list_name), re_path(r'^change/(?P<homework_id>\d+)/(?P<pk>\d+)/$', self.wrapper(self.change_view), name=self.get_change_name), re_path(r'^del/(?P<homework_id>\d+)/(?P<pk>\d+)/$', self.wrapper(self.delete_view), name=self.get_del_name), re_path(r'^download/(?P<pk>\d+)/$', self.wrapper(self.download), name=self.get_url_name('download')), ] patterns.extend(self.extra_url()) return patterns def display_edit(self, model=None, is_header=None, *args, **kwargs): """ :param model: model即数据库表对象 :param is_header: 是否是表头字段 :return: 显示除了表的字段verbose_name外,自添加字段 """ if is_header: return "编辑" homework_id = kwargs.get('homework_id') return mark_safe( '<a href="%s">编辑</a>' % self.reverse_change_url(pk=model.pk, homework_id=homework_id)) def display_edit_del(self, model=None, is_header=None, *args, **kwargs): if is_header: return '操作' homework_id = kwargs.get('homework_id') tpl = '<a href="%s">编辑</a> <a href="%s">删除</a>' % ( self.reverse_change_url(pk=model.pk, homework_id=homework_id), self.reverse_delete_url(pk=model.pk, homework_id=homework_id)) return mark_safe(tpl) def get_add_btn(self, request, *args, **kwargs): return None def get_model_queryset(self, request, *args, **kwargs): homework_id = kwargs.get('homework_id') return self.model_class.objects.filter(homework_id=homework_id) def action_multi_check(self, request, *args, **kwargs): """ 批量删除钩子,如果想要定制执行成功后的返回值,那么就为action函数设置返回值即可。 :return: """ pk_list = request.POST.getlist('pk') # self.model_class.objects.filter(id__id=pk_list).update(status=4) for pk in pk_list: home_detail_object = self.model_class.objects.filter(id=pk).first() home_detail_object.status = 4 home_detail_object.save() action_multi_check.text = "批量批改" def display_download(self, model=None, is_header=None, *args, **kwargs): if is_header: return '作业文件' name = "%s:%s" % ( self.site.namespace, self.get_url_name('download'), ) reverse_url = reverse(name, kwargs={'pk': model.pk}) return mark_safe('<a target="_blank" href="%s">下载作业</a>' % reverse_url) def download(self, request, pk, *args, **kwargs): """ 下载学员的作业 :param request: :param pk: :param args: :param kwargs: :return: """ file = str(self.model_class.objects.filter(id=pk).first().file) file_link = settings.BASE_FILE + file return HttpResponse('<a href="%s" download="%s">点我下载</a>' % (file_link, file)) action_list = [ action_multi_check, ] list_display = [ StartXHandler.display_checkbox, get_m2m_display('学生', 'student'), get_field_display('作业状态', 'status'), display_download, 'critic' ]
class HomeworkDetailHandler(PermissionHandler, StartXHandler): model_form_class = HomeworkDetailModelForm def get_add_btn(self, request, *args, **kwargs): return def get_urls(self): """预留的重新自定义url钩子函数,主要是覆盖掉默认的url,并设置name别名""" patterns = [ re_path(r'^list/(?P<homework_id>\d+)/$', self.wrapper(self.changelist), name=self.get_list_name), re_path(r'^change/(?P<homework_id>\d+)/(?P<pk>\d+)/$', self.wrapper(self.change_view), name=self.get_change_name), re_path(r'^download/(?P<pk>\d+)/$', self.wrapper(self.download), name=self.get_url_name('download')), ] patterns.extend(self.extra_url()) return patterns def display_edit(self, model=None, is_header=None, *args, **kwargs): if is_header: return '操作' homework_id = kwargs.get('homework_id') tpl = '<a href="%s">编辑</a>' % self.reverse_change_url(pk=model.pk, homework_id=homework_id) return mark_safe(tpl) def get_list_display(self, request, *args, **kwargs): """ 预留的钩子函数 :return: 为不同权限的用户设置预留的扩展,自定义显示列 """ value = [] if self.list_display: value.extend(self.list_display) value.append(type(self).display_edit) return value def get_model_queryset(self, request, *args, **kwargs): homework_id = kwargs.get('homework_id') user_id = request.session['userinfo']['id'] user_obj = models.Tutor.objects.filter(account_id=user_id).first() # 登录的导师只能看自己所对应的所有学员作业情况 return self.model_class.objects.filter(homework_id=homework_id, teacher=user_obj) def display_download(self, model=None, is_header=None, *args, **kwargs): if is_header: return '作业文件' name = "%s:%s" % (self.site.namespace, self.get_url_name('download'),) reverse_url = reverse(name, kwargs={'pk': model.pk}) return mark_safe('<a target="_blank" href="%s">下载作业</a>' % reverse_url) def download(self, request, pk, *args, **kwargs): """ 下载学员的作业 :param request: :param pk: :param args: :param kwargs: :return: """ file = str(self.model_class.objects.filter(id=pk).first().file) file_link = settings.BASE_FILE + file return HttpResponse('<a href="%s" download="%s">点我下载</a>' % (file_link, file)) list_display = [ 'homework', get_m2m_display('学生', 'student'), 'status', display_download, 'critic'] search_list = ['student__contains']
class PublicCustomerHandler(PermissionHandler, StartXHandler): """公户设置""" def get_model_queryset(self, reqeust, *args, **kwargs): return self.model_class.objects.filter(consultant__isnull=True) def display_record(self, model=None, is_header=None, *args, **kwargs): if is_header: return '跟进记录' record_url = self.reverse_commons_url(self.get_url_name('record'), pk=model.pk) return mark_safe('<a href="%s">查看跟进记录</a>' % record_url) def record_view(self, request, pk): records = self.model_class.objects.filter( id=pk).first().consultrecord_set.all() return render(request, 'record.html', {'records': records}) def extra_url(self): patterns = [ re_path(r'^record/(?P<pk>\d+)/$', self.wrapper(self.record_view), name=self.get_url_name('record')) ] return patterns def action_multi_pull(self, request, *args, **kwargs): """ 批量将公户客户申请拉取到私户 :return: """ pk_list = request.POST.getlist('pk') current_consultant_id = request.session['staffinfo']['staff_id'] # 做验证 current_consultant_customers = models.Customer.objects.filter( consultant_id=current_consultant_id, status=2).count() if len(pk_list) + current_consultant_customers > 150: return HttpResponse('超出最大值,您已有 %s 个客户,最多还能添加 %s 个客户' % (current_consultant_customers, 150 - current_consultant_customers)) # 数据库中加锁 flag = False with transaction.atomic(): # 事务 queryset = models.Customer.objects.filter(id__in=pk_list, status=2, consultant__isnull=True) origin_queryset = queryset.select_for_update() # 加数据库锁 if len(origin_queryset) == len(pk_list): queryset.update(consultant_id=current_consultant_id) flag = True if not flag: return HttpResponse('手速太慢了,选中的客户已被其他人申请,请重新选择') action_multi_pull.text = "加入我的私户" action_list = [ action_multi_pull, ] list_display = [ StartXHandler.display_checkbox, 'name', 'qq', get_field_display('报名状态', 'status'), get_m2m_display('咨询课程', 'course'), display_record ] model_form_class = PublicModelForm