def _get_entrance_steps_for_user(self, user): # It's here to avoid cyclic imports import modules.entrance.models as entrance_models steps = self.school.entrance_steps.all() enrolled_to_session_ids = [] enrolled_to_parallel_ids = [] status = entrance_models.EntranceStatus.get_visible_status( self.school, user) if status is not None and status.is_enrolled and status.is_approved: sessions_and_parallels = status.sessions_and_parallels.filter( selected_by_user=True) enrolled_to_session_ids = nested_query_list( sessions_and_parallels.values_list('session_id', flat=True)) enrolled_to_parallel_ids = nested_query_list( sessions_and_parallels.values_list('parallel_id', flat=True)) elif status is None or not status.is_enrolled: # If user is not enrolled, filter out all steps # marked as 'visible_only_for_enrolled' steps = steps.filter(Q(visible_only_for_enrolled=False)) # Filter only steps for session and parallel which user has been enrolled in # (or steps with no defined session and parallel) steps = steps.filter( Q(session__isnull=True) | Q(session_id__in=enrolled_to_session_ids)) steps = steps.filter( Q(parallel__isnull=True) | Q(parallel_id__in=enrolled_to_parallel_ids)) return steps.order_by('order')
def teacher_task_checks(request, group_name, teacher_id, task_id): checking_group = get_object_or_404( models.CheckingGroup, school=request.school, short_name=group_name, ) teacher = get_object_or_404(users.models.User, pk=teacher_id) task = get_object_or_404(models.FileEntranceExamTask, id=task_id) if not checking_group.tasks.filter(id=task.id).exists(): return HttpResponseNotFound() group_user_ids = nested_query_list(checking_group.group.user_ids) checks = (models.CheckedSolution.objects.filter( solution__user_id__in=group_user_ids, solution__task_id=task_id, checked_by=teacher).order_by('-created_at').select_related( 'solution__user').select_related('solution__task')) return render( request, 'entrance/staff/teacher_checks.html', { 'group': checking_group, 'teacher': teacher, 'task': task, 'checks': checks, })
def checking_group_checks(request, group_name): checking_group = get_object_or_404( models.CheckingGroup, school=request.school, short_name=group_name, ) tasks = list(checking_group.tasks.order_by('order')) user_ids = nested_query_list(checking_group.group.user_ids) task_ids = [t.id for t in tasks] checks = list( models.CheckedSolution.objects.filter( solution__user_id__in=user_ids, solution__task_id__in=task_ids, ).order_by('-created_at').select_related( 'solution__user').select_related('solution__task')) return render( request, 'entrance/staff/group_checks.html', { 'group': checking_group, 'users': users, 'tasks': tasks, 'checks': checks, })
def teacher_checks(request, group_name, teacher_id): checking_group = get_object_or_404( models.CheckingGroup, school=request.school, short_name=group_name, ) teacher = get_object_or_404(users.models.User, pk=teacher_id) group_user_ids = nested_query_list(checking_group.group.user_ids) checks = (models.CheckedSolution.objects.filter( solution__user_id__in=group_user_ids, checked_by=teacher).order_by('-created_at').select_related( 'solution__user').select_related('solution__task')) return render(request, 'entrance/staff/teacher_checks.html', { 'group': checking_group, 'teacher': teacher, 'checks': checks, })
def check_group(request, group_name): checking_group = get_object_or_404(models.CheckingGroup, school=request.school, short_name=group_name) _remove_old_checking_locks() tasks = list(checking_group.tasks.order_by('order')) group_user_ids = nested_query_list(checking_group.group.user_ids) for task in tasks: task.solutions_count = users.models.User.objects.filter( id__in=group_user_ids, entrance_exam_solutions__task=task).distinct().count() task.checks = models.CheckedSolution.objects.filter( solution__task=task, solution__user_id__in=group_user_ids) task.checked_solutions_count = task.checks.values_list( 'solution__user_id', flat=True).distinct().count() task.checks_count = task.checks.count() group_checks = models.CheckedSolution.objects.filter( solution__task__in=tasks, solution__user_id__in=group_user_ids) total_solutions_count = sum(task.solutions_count for task in tasks) total_checked_solutions_count = sum(task.checked_solutions_count for task in tasks) total_checks_count = sum(task.checks_count for task in tasks) total_teachers_count = (group_checks.order_by('checked_by_id').values( 'checked_by_id').distinct().count()) total_users_count = len(group_user_ids) for task in tasks: task.checks = list(task.checks.order_by('-created_at')[:20]) return render( request, 'entrance/staff/check_group.html', { 'group': checking_group, 'tasks': tasks, 'total_solutions_count': total_solutions_count, 'total_checks_count': total_checks_count, 'total_checked_solutions_count': total_checked_solutions_count, 'total_teachers_count': total_teachers_count, 'total_users_count': total_users_count, })
def check_users_task(request, task_id, user_id, group_name=None): _remove_old_checking_locks() if group_name is not None: checking_group = get_object_or_404(models.CheckingGroup, school=request.school, short_name=group_name) else: checking_group = None user = get_object_or_404(users.models.User, id=user_id) task = get_object_or_404(models.FileEntranceExamTask, id=task_id) task.mark_field_id = ( forms.FileEntranceExamTasksMarkForm.FIELD_ID_TEMPLATE % task.id) task.comment_field_id = ( forms.FileEntranceExamTasksMarkForm.COMMENT_ID_TEMPLATE % task.id) if checking_group is None: group_user_ids = list({ user_id for g in request.school.entrance_checking_groups.all() for user_id in g.group.user_ids }) else: # Select users from group group_user_ids = checking_group.group.user_ids task.total_solutions_count = users.models.User.objects.filter( id__in=nested_query_list(group_user_ids), entrance_exam_solutions__task=task).distinct().count() task.checked_solutions_count = users.models.User.objects.filter( id__in=nested_query_list(group_user_ids), entrance_exam_solutions__task=task, entrance_exam_solutions__checks__isnull=False).distinct().count() locked_by_me = True with transaction.atomic(): lock = models.CheckingLock.objects.filter( user=user, task=task, ).first() if lock is None: lock = models.CheckingLock.objects.create( user_id=user_id, task_id=task_id, locked_by=request.user, ) else: locked_by_me = lock.locked_by_id == request.user.id base_entrance_level = upgrades.get_base_entrance_level( request.school, user) level_upgrades = models.EntranceLevelUpgrade.objects.filter( upgraded_to__school=request.school, user=user) solutions = task.solutions.filter(user=user).order_by('-created_at') if not solutions.exists(): lock.delete() messages.add_message(request, messages.INFO, 'Этот пользователь не решал выбранную задачу') if checking_group is None: return redirect('school:entrance:enrolling_user', school_name=request.school.short_name, user_id=user.id) return redirect('school:entrance:check_task', school_name=request.school.short_name, group_name=group_name, task_id=task.id) solutions = list(solutions) last_solution = solutions[0] if request.method == 'POST': if 'refuse' in request.POST: lock.delete() return redirect( 'school:entrance:check', school_name=request.school.short_name, ) mark_form = forms.FileEntranceExamTasksMarkForm([task], request.POST, with_comment=True) if mark_form.is_valid(): score = mark_form.cleaned_data[task.mark_field_id] comment = mark_form.cleaned_data[task.comment_field_id] models.CheckedSolution.objects.create(solution=last_solution, checked_by=request.user, score=score, comment=comment) lock.delete() messages.add_message( request, messages.INFO, 'Баллы пользователю %s успешно сохранены' % (user.get_full_name(), )) if checking_group is None: return redirect('school:entrance:enrolling_user', school_name=request.school.short_name, user_id=user.id) return redirect('school:entrance:check_task', school_name=request.school.short_name, group_name=group_name, task_id=task.id) else: mark_form = forms.FileEntranceExamTasksMarkForm([task], with_comment=True) checks = list( models.CheckedSolution.objects.filter( solution=last_solution).order_by('-created_at')) last_mark = None if len(checks) == 0 else checks[0].score if last_mark is not None: mark_form.set_initial_mark(task.id, last_mark) checking_comments = models.CheckingComment.objects.filter( school=request.school, user=user) add_checking_comment_form = forms.AddCheckingCommentForm() return render( request, 'entrance/staff/check_users_task.html', { 'group': checking_group, 'user_for_checking': user, 'locked_by_me': locked_by_me, 'task': task, 'base_entrance_level': base_entrance_level, 'level_upgrades': level_upgrades, 'solutions': solutions, 'last_solution': last_solution, 'checks': checks, 'last_mark': last_mark, 'checking_comments': checking_comments, 'add_checking_comment_form': add_checking_comment_form, 'mark_form': mark_form })
def checking_group_teachers(request, group_name): checking_group = get_object_or_404( models.CheckingGroup, school=request.school, short_name=group_name, ) user_ids = list(checking_group.group.user_ids) tasks = list_to_dict(checking_group.tasks.order_by('order'), lambda task: task.id, lambda task: task) task_ids = list(tasks.keys()) checks = models.CheckedSolution.objects.filter( solution__user_id__in=user_ids, solution__task_id__in=task_ids, ).select_related('solution', 'checked_by') checks_grouped_by_teacher = checks.values('checked_by_id') checks_grouped_by_task_and_teacher = (checks.values( 'solution__task_id', 'checked_by_id')) teacher_solutions_count = list_to_dict( checks_grouped_by_teacher.annotate( count=Count('solution_id', distinct=True)), operator.itemgetter('checked_by_id'), operator.itemgetter('count'), ) teacher_task_solutions_count = list_to_dict( checks_grouped_by_task_and_teacher.annotate( count=Count('solution_id', distinct=True)), operator.itemgetter('checked_by_id'), operator.itemgetter('solution__task_id'), operator.itemgetter('count'), ) average_scores = list_to_dict( checks_grouped_by_task_and_teacher.annotate( average_score=sql_round_with_precision( Cast(Sum('score'), FloatField()) / Cast(Count('score'), FloatField()), 2)), operator.itemgetter('checked_by_id'), operator.itemgetter('solution__task_id'), operator.itemgetter('average_score'), ) teacher_tasks = group_by( checks_grouped_by_task_and_teacher.distinct(), operator.itemgetter('checked_by_id'), extract_value_function=operator.itemgetter('solution__task_id')) teacher_ids = nested_query_list( checks.order_by('checked_by_id').values_list('checked_by_id', flat=True).distinct()) teachers = users.models.User.objects.filter(id__in=teacher_ids) ordered_teachers = sorted(teachers, key=lambda t: teacher_solutions_count[t.id], reverse=True) return render( request, 'entrance/staff/group_teachers.html', { 'group': checking_group, 'tasks': tasks, 'teachers': ordered_teachers, 'teacher_solutions_count': teacher_solutions_count, 'teacher_tasks': teacher_tasks, 'teacher_task_solutions_count': teacher_task_solutions_count, 'average_scores': average_scores, })