def select_students(self, request, tl, one, two, module, extra, prog): # Get preregistered and enrolled students try: sec = ClassSection.objects.get(id=extra) except (ValueError, ClassSection.DoesNotExist): raise ESPError( 'Class section not found. If you came from a link on our site, please notify the webmasters.', log=False) students_list = sec.students_prereg() if request.method == 'POST': # Handle form submission # result_strs = [] data = request.POST.copy() sections_dict = {} for key in data: key_dir = key.split('_') if key_dir[0] == 'regstatus' and len(key_dir) == 3: student_id = int(key_dir[1]) sec_id = int(key_dir[2]) if sec_id not in sections_dict: sections_dict[sec_id] = [{ 'id': student_id, 'status': data[key] }] else: sections_dict[sec_id].append({ 'id': student_id, 'status': data[key] }) for sec_id in sections_dict: sec = ClassSection.objects.get(id=sec_id) sec.cache['students'] = None sec.cache['num_students'] = None for item in sections_dict[sec_id]: student = ESPUser.objects.get(id=item['id']) ignore = False value = item['status'] if value == 'enroll': verb_name = 'Enrolled' elif value == 'reject': verb_name = 'Rejected' else: ignore = True if not ignore: rel = RegistrationType.get_map( include=['Enrolled', 'Rejected'], category='student')[verb_name] other_regs = sec.getRegistrations(student).filter( relationship__name__in=['Enrolled', 'Rejected']) found = False for reg in other_regs: if not found and reg.relationship == rel: found = True else: reg.expire() if not found: new_reg = StudentRegistration(user=student, relationship=rel, section=sec) new_reg.save() # Jazz up this information a little #Not having much luck with query count/performance when selecting related parent_class and parent_class__category #Creating a lookup dict instead to strip out duplicate ClassSubject instances student_regs = StudentRegistration.valid_objects().filter(user__in=students_list) \ .order_by('start_date').select_related('section','user','relationship') student_regs = student_regs.filter( section__parent_class__parent_program=self.program) student_sections_dict = defaultdict(set) student_reg_dict = defaultdict(set) #need a unique set of parent_class ids #creating lookup dicts to avoid hitting database(was not solved with #select_related or prefecth_related parent_class_id_set = set() sections = set() for reg in student_regs: student_sections_dict[reg.user].add(reg.section) display_name = reg.relationship.displayName or reg.relationship.name sections.add(reg.section) parent_class_id_set.add(reg.section.parent_class_id) student_reg_dict['%i_%i' % ( reg.user.id, reg.section.id, )].add(display_name) subjects = ClassSubject.objects.filter( id__in=parent_class_id_set).select_related('category') subject_categories_dict = dict([(s.id, (s, s.category)) for s in subjects]) for student in students_list: student.bits = student_reg_dict['%i_%i' % ( student.id, sec.id, )] #this is a bit of a problem because it produces the side affect of application #creation if not found student.app = student.getApplication(self.program, False) student.other_classes = [] for section in student_sections_dict[student]: parent_class, category = subject_categories_dict.get( section.parent_class_id) regtypes = student_reg_dict['%i_%i' % ( student.id, section.id, )] section_row = (section, regtypes, parent_class, category) student.other_classes.append(section_row) preregs = sec.getRegistrations(student).exclude( relationship__name__in=['Enrolled', 'Rejected']) if preregs.count() != 0: student.added_class = preregs[0].start_date if 'Enrolled' in student.bits: student.enrolled = True elif 'Rejected' in student.bits: student.rejected = True # Detect if there is an application module from esp.program.modules.handlers.studentjunctionappmodule import StudentJunctionAppModule has_app_module = False for module in prog.getModules(): if isinstance(module, StudentJunctionAppModule): has_app_module = True return render_to_response( self.baseDir() + 'select_students.html', request, { 'has_app_module': has_app_module, 'prog': prog, 'sec': sec, 'students_list': students_list })
def save_priorities(self, request, tl, one, two, module, extra, prog): """ Saves the priority preferences for student registration phase 2. """ if not 'json_data' in request.POST: return HttpResponseBadRequest('JSON data not included in request.') try: json_data = json.loads(request.POST['json_data']) except ValueError: return HttpResponseBadRequest('JSON data mis-formatted.') try: [timeslot_id] = json_data.keys() except ValueError: return HttpResponseBadRequest('JSON data mis-formatted.') if not isinstance(json_data[timeslot_id], dict): return HttpResponseBadRequest('JSON data mis-formatted.') timeslot = Event.objects.get(pk=timeslot_id) priorities = json_data[timeslot_id] for rel_index, cls_id in priorities.items(): rel_name = 'Priority/%s' % rel_index rel = RegistrationType.objects.get(name=rel_name, category='student') # Pull up any registrations that exist (including expired ones) srs = StudentRegistration.objects.annotate( Min('section__meeting_times__start')) srs = srs.filter(user=request.user, section__parent_class__parent_program=prog, section__meeting_times__start__min=timeslot.start, relationship=rel) if cls_id == '': # Blank: nothing selected, expire existing registrations for sr in srs: sr.expire() continue cls_id = int(cls_id) sec = ClassSection.objects.annotate(Min('meeting_times__start')) try: sec = sec.get(parent_class=cls_id, parent_class__parent_program=prog, meeting_times__start__min=timeslot.start) except (ClassSection.DoesNotExist, ClassSection.MultipleObjectsReturned): # XXX: what if a class has multiple sections in a timeblock? logger.warning( "Could not save priority for class %s in " "timeblock %s", cls_id, timeslot_id) continue # sanity checks if (not sec.status > 0 or not sec.parent_class.status > 0): logger.warning( "Class '%s' was not approved. Not letting " "user '%s' register.", sec, request.user) if (not sec.parent_class.grade_min <= request.user.getGrade(prog) or not sec.parent_class.grade_max >= request.user.getGrade(prog)): logger.warning( "User '%s' not in class grade range; not " "letting them register.", request.user) continue if not srs.exists(): # Create a new registration sr = StudentRegistration(user=request.user, relationship=rel) else: # Pull the first StudentRegistration, expire the others for sr in srs[1:]: sr.expire() sr = srs[0] # Modify as needed to ensure the section is correct and # expiration date is valid if sr.section_id is None or sr.section.parent_class.id != cls_id: sr.section = sec sr.unexpire(save=False) sr.save() return self.goToCore(tl)
def select_students(self, request, tl, one, two, module, extra, prog): # Get preregistered and enrolled students try: sec = ClassSection.objects.filter(id=extra)[0] except: raise ESPError( False ), 'Class section not found. If you came from a link on our site, please notify the webmasters.' students_list = sec.students_prereg() if request.method == 'POST': # Handle form submission # result_strs = [] data = request.POST.copy() sections_dict = {} for key in data: key_dir = key.split('_') if key_dir[0] == 'regstatus' and len(key_dir) == 3: student_id = int(key_dir[1]) sec_id = int(key_dir[2]) if sec_id not in sections_dict: sections_dict[sec_id] = [{ 'id': student_id, 'status': data[key] }] else: sections_dict[sec_id].append({ 'id': student_id, 'status': data[key] }) for sec_id in sections_dict: sec = ClassSection.objects.get(id=sec_id) sec.cache['students'] = None sec.cache['num_students'] = None for item in sections_dict[sec_id]: student = ESPUser(User.objects.get(id=item['id'])) ignore = False value = item['status'] if value == 'enroll': verb_name = 'Enrolled' elif value == 'reject': verb_name = 'Rejected' else: ignore = True if not ignore: rel = RegistrationType.get_map( include=['Enrolled', 'Rejected'], category='student')[verb_name] other_regs = sec.getRegistrations(student).filter( relationship__name__in=['Enrolled', 'Rejected']) found = False for reg in other_regs: if not found and reg.relationship == rel: found = True else: reg.expire() # result_strs.append('Expired: %s' % bit) if not found: new_reg = StudentRegistration(user=student, relationship=rel, section=sec) new_reg.save() # Jazz up this information a little for student in students_list: student.bits = sec.getRegVerbs(student) student.app = student.getApplication(self.program, False) student.other_classes = [ (sec2, sec2.getRegVerbs(student)) for sec2 in student.getSections(self.program).exclude( id=sec.id) ] preregs = sec.getRegistrations(student).exclude( relationship__name__in=['Enrolled', 'Rejected']) if preregs.count() != 0: student.added_class = preregs[0].start_date if 'Enrolled' in student.bits: student.enrolled = True elif 'Rejected' in student.bits: student.rejected = True # Detect if there is an application module from esp.program.modules.handlers.studentjunctionappmodule import StudentJunctionAppModule has_app_module = False for module in prog.getModules(): if isinstance(module, StudentJunctionAppModule): has_app_module = True return render_to_response( self.baseDir() + 'select_students.html', request, { 'has_app_module': has_app_module, 'prog': prog, 'sec': sec, 'students_list': students_list })
def save_priorities(self, request, tl, one, two, module, extra, prog): """ Saves the priority preferences for student registration phase 2. """ if not 'json_data' in request.POST: return HttpResponseBadRequest('JSON data not included in request.') try: json_data = json.loads(request.POST['json_data']) except ValueError: return HttpResponseBadRequest('JSON data mis-formatted.') try: [timeslot_id] = json_data.keys() except ValueError: return HttpResponseBadRequest('JSON data mis-formatted.') if not isinstance(json_data[timeslot_id], dict): return HttpResponseBadRequest('JSON data mis-formatted.') timeslot = Event.objects.get(pk=timeslot_id) priorities = json_data[timeslot_id] for rel_index, cls_id in priorities.items(): rel_name = 'Priority/%s' % rel_index rel = RegistrationType.objects.get(name=rel_name, category='student') # Pull up any registrations that exist (including expired ones) srs = StudentRegistration.objects.annotate( Min('section__meeting_times__start')) srs = srs.filter( user=request.user, section__parent_class__parent_program=prog, section__meeting_times__start__min=timeslot.start, relationship=rel) if cls_id == '': # Blank: nothing selected, expire existing registrations for sr in srs: sr.expire() continue cls_id = int(cls_id) sec = ClassSection.objects.annotate(Min('meeting_times__start')) try: sec = sec.get(parent_class=cls_id, parent_class__parent_program=prog, meeting_times__start__min=timeslot.start) except (ClassSection.DoesNotExist, ClassSection.MultipleObjectsReturned): # XXX: what if a class has multiple sections in a timeblock? logger.warning("Could not save priority for class %s in " "timeblock %s", cls_id, timeslot_id) continue # sanity checks if (not sec.status > 0 or not sec.parent_class.status > 0): logger.warning("Class '%s' was not approved. Not letting " "user '%s' register.", sec, request.user) if (not sec.parent_class.grade_min <= request.user.getGrade(prog) or not sec.parent_class.grade_max >= request.user.getGrade(prog)): logger.warning("User '%s' not in class grade range; not " "letting them register.", request.user) continue if not srs.exists(): # Create a new registration sr = StudentRegistration( user=request.user, relationship=rel) else: # Pull the first StudentRegistration, expire the others for sr in srs[1:]: sr.expire() sr = srs[0] # Modify as needed to ensure the section is correct and # expiration date is valid if sr.section_id is None or sr.section.parent_class.id != cls_id: sr.section = sec sr.unexpire(save=False) sr.save() return self.goToCore(tl)