def save_assignments(request):    
    with atomic():
        #Run new session creation first
        for key in request.POST:
            parts = key.split("_")
            if len(parts) != 4:
                continue
            
            slotID, studentID, keyType = parts[1:]
            
            if keyType == 'option':             
                value = request.POST[key]
                    
                slot = EnrichmentSlot.objects.get(pk=slotID)
                student = Student.objects.get(pk=studentID)

                if not canEditSignup(request.user, slot, student):
                    raise PermissionDenied()
                
                if value:
                    try:
                        option = EnrichmentOption.objects.get(pk=value)
                    except EnrichmentOption.DoesNotExist:
                        logger.error("Enrichment option session {id:} not found".format(id=value))
                        option = None
                else:
                    option = None
                
                #If we're clearing the signup, just delete all possible matching objects
                if not option:
                    EnrichmentSignup.objects.filter(slot=slot, student=student).delete()
                
                #Find and update the existing signup if it exists, otherwide create one
                else:                    
                    try:
                        signup = EnrichmentSignup.objects.get(slot=slot, student=student)
                        
                    except EnrichmentSignup.DoesNotExist:
                        signup = EnrichmentSignup(student=student, slot=slot)
                    
                    signup.enrichment_option = option
                    signup.save()
        
        #Do it again, now that our signups should have been reconciled
        for key in request.POST:
            parts = key.split("_")
            if len(parts) != 4:
                continue
            
            slotID, studentID, keyType = parts[1:]
            
            if keyType == 'adminlock':
                value = request.POST[key]
            
                slot = EnrichmentSlot.objects.get(pk=slotID)
                student = Student.objects.get(pk=studentID)
                
                if not canEditSignup(request.user, slot, student):
                    raise PermissionDenied()
                
                if not request.user.has_perm("enrichmentmanager.can_set_admin_lock"):
                    raise PermissionDenied()
                
                try:
                    signup = EnrichmentSignup.objects.get(slot=slot, student=student)
            
                    if value.lower() in ("1", "true"):
                        value = True
                    elif value.lower() in ("0", "false"):
                        value = False
                
                    signup.admin_lock = value
                    signup.save()

                except EnrichmentSignup.DoesNotExist:
                    logger.error("Setting a lock on a non-existent enrichment signup")

    return redirect(request.POST["next"])
def select_for(context, slot, student):
    
    if student.lockout:
        return '<p class="readOnlySignup">{lockout}</p>'.format(lockout=student.lockout)
    
    canEdit = canEditSignup(context.request.user, slot, student)
    
    key = "slot_{slot_id}_{student_id}".format(slot_id=slot.id, student_id=student.id)
    
    if canEdit:
        out = StringIO()
        choices = context['slotChoices'][slot]

        out.write('<select name="{key}_option" class="slotSelector saveTrack">'.format(key=key))
        out.write('<option value="">--</option>')
    
        selected = context['relatedSignups'].get(key)
        
        preferredChoices = StringIO()
        otherChoices = StringIO()
        associatedTeachers = student.associated_teachers.all()
        
        for choice in choices:
            if choice.teacher in associatedTeachers:
                if selected == choice.id:
                    preferredChoices.write('<option value="{choice_id}" selected="selected">{choice_name}</option>'.format(choice_id=choice.id, choice_name=str(choice)))
                else:
                    preferredChoices.write('<option value="{choice_id}">{choice_name}</option>'.format(choice_id=choice.id, choice_name=str(choice)))
            else:
                if selected == choice.id:
                    otherChoices.write('<option value="{choice_id}" selected="selected">{choice_name}</option>'.format(choice_id=choice.id, choice_name=str(choice)))
                else:
                    otherChoices.write('<option value="{choice_id}">{choice_name}</option>'.format(choice_id=choice.id, choice_name=str(choice)))
        
        preferredChoices = preferredChoices.getvalue()
        otherChoices = otherChoices.getvalue()
        
        if preferredChoices and otherChoices:
            out.write(preferredChoices)
            out.write('<option value="">--</option>')
            out.write(otherChoices)
        
        else:
            out.write(preferredChoices)
            out.write(otherChoices)
                
        out.write("</select>")
        
        if context.request.user.has_perm("enrichmentmanager.can_set_admin_lock"):
            #TODO: Horribly ineffecient
            try:
                signup = EnrichmentSignup.objects.get(slot=slot, student=student)
            except EnrichmentSignup.DoesNotExist:
                signup = None
            
            if signup and signup.admin_lock:
                out.write('<input type="checkbox" title="Admin Lockout" name="{key}_adminlock" class="saveTrack adminLock" checked />'.format(key=key))
            else:
                out.write('<input type="checkbox" title="Admin Lockout" name="{key}_adminlock" class="saveTrack adminLock" />'.format(key=key))
        
        return out.getvalue()
    
    else:
        selectedID = context['relatedSignups'].get(key)
        
        if selectedID:
            #Ineffecient, will generate many queries if viewing in read only mode
            selectedChoice = EnrichmentOption.objects.get(pk=selectedID)

            return '<p class="readOnlySignup">{option}</p>'.format(option=selectedChoice)
        
        return ""