def save(self, entered_by, group=None, newsitem=True): """Save the grade. entered_by must be one of: (1) the Person object of the person who entered the grade, (2) the userid of the person who entered the grade, (3) None ONLY if this was a result of a calculation newsitem controls the posting of a NewsItem for the student. """ super(LetterGrade, self).save() entered_by = get_entry_person(entered_by) if entered_by: gh = GradeHistory(activity=self.activity, member=self.member, entered_by=entered_by, activity_status=self.activity.status, letter_grade=self.letter_grade, grade_flag=self.flag, comment=self.comment, mark=None, group=group) gh.save() else: assert self.flag == 'CALC' if self.activity.status=="RLS" and newsitem and self.flag != "NOGR": # new grade assigned, generate news item only if the result is released n = NewsItem(user=self.member.person, author=None, course=self.activity.offering, source_app="grades", title="%s grade available" % (self.activity.name), content='A new grade for %s in %s is available.' % (self.activity.name, self.activity.offering.name()), url=self.get_absolute_url()) n.save()
def save(self, newsitem=True, newsitem_author=None, *args, **kwargs): for f in self.config: # if 'weekly' in False is invalid, so we have to check if self.config[f] is iterable # before we check for 'weekly' or 'total' if hasattr(self.config[f], '__iter__'): if 'weekly' in self.config[f]: self.config[f]['weekly'] = _round_hours( self.config[f]['weekly']) if 'total' in self.config[f]: self.config[f]['total'] = _round_hours( self.config[f]['total']) super(TUG, self).save(*args, **kwargs) if newsitem: n = NewsItem( user=self.member.person, author=newsitem_author, course=self.member.offering, source_app='ta', title='%s Time Use Guideline Changed' % (self.member.offering.name()), content= 'Your Time Use Guideline for %s has been changed. If you have not already, please review it with the instructor.' % (self.member.offering.name()), url=self.get_absolute_url()) n.save()
def send_notification(self, run): n = NewsItem( user= self.person, source_app='reports', title="Completed Run: " + self.report.name + " : " + run.slug, url= reverse('reports.views.view_run', kwargs={'report':self.report.slug, 'run':run.slug}), content= "You have a scheduled report that has completed! \n" + self.report.description ); n.save()
def save(self, entered_by, mark=None, newsitem=True, group=None, is_temporary=False): """Save the grade. entered_by must be one of: (1) the Person object of the person who entered the grade, (2) the userid of the person who entered the grade, (3) None ONLY if this was a result of a calculation (or for a temporary save that will be re-saved later) mark is a reference to the StudentActivityMark or GroupActivity mark, if that's where the grade came from newsitem controls the posting of a NewsItem for the student. """ if self.flag == "NOGR": # make sure "no grade" values have a zero: just in case the value is used in some other calc self.value = 0 super(NumericGrade, self).save() entered_by = get_entry_person(entered_by) if bool(mark) and not mark.id: raise ValueError( "ActivityMark must be saved before calling setMark.") if entered_by: gh = GradeHistory(activity=self.activity, member=self.member, entered_by=entered_by, activity_status=self.activity.status, numeric_grade=self.value, grade_flag=self.flag, comment=self.comment, mark=mark, group=group) gh.save() else: assert (self.flag == 'CALC') or (is_temporary and self.flag == 'NOGR') if self.activity.status == "RLS" and newsitem and self.flag not in [ "NOGR", "CALC" ]: # new grade assigned, generate news item only if the result is released n = NewsItem(user=self.member.person, author=None, course=self.activity.offering, source_app="grades", title="%s grade available" % (self.activity.name), content='A new grade for %s in %s is available.' % (self.activity.name, self.activity.offering.name()), url=self.activity.get_absolute_url()) n.save()
def failure_notification(self, failed_run): if failed_run.manual: return every_sysadmin = [role.person for role in Role.objects.filter(role='SYSA')] for sysadmin in every_sysadmin: n = NewsItem( user=sysadmin, source_app='reports', title="Failed Report: " + self.name, url= reverse('reports.views.view_run', kwargs={'report':self.slug, 'run':failed_run.slug}), content= "A run has failed! \n" + self.description ); n.save()
def save(self): new_submit = (self.id is None) super(GroupSubmission, self).save() if new_submit: member_list = GroupMember.objects.filter(group=self.group, activity=self.activity) for member in member_list: n = NewsItem(user = member.student.person, author=self.creator.person, course=member.group.courseoffering, source_app="submit_group", title="New Group Submission", content="Your group member %s has made a submission for %s." % (self.creator.person.name(), self.activity.name), url=reverse('submission.views.show_components', kwargs={'course_slug': self.group.courseoffering.slug, 'activity_slug': member.activity.slug}) ) n.save()
def save(self): new_submit = (self.id is None) super(GroupSubmission, self).save() if new_submit: member_list = GroupMember.objects.filter(group=self.group, activity=self.activity) for member in member_list: n = NewsItem(user = member.student.person, author=self.creator.person, course=member.group.courseoffering, source_app="submit_group", title="New Group Submission", content="Your group member %s has made a submission for %s." % (self.creator.person.name(), self.activity.name), url=reverse('offering:submission:show_components', kwargs={'course_slug': self.group.courseoffering.slug, 'activity_slug': member.activity.slug}) ) n.save()
def save(self, newsitem=True, newsitem_author=None, *args, **kwargs): for f in self.config: # if 'weekly' in False is invalid, so we have to check if self.config[f] is iterable # before we check for 'weekly' or 'total' if hasattr(self.config[f], '__iter__'): if 'weekly' in self.config[f]: self.config[f]['weekly'] = _round_hours(self.config[f]['weekly']) if 'total' in self.config[f]: self.config[f]['total'] = _round_hours(self.config[f]['total']) super(TUG, self).save(*args, **kwargs) if newsitem: n = NewsItem(user=self.member.person, author=newsitem_author, course=self.member.offering, source_app='ta', title='%s Time Use Guideline Changed' % (self.member.offering.name()), content='Your Time Use Guideline for %s has been changed. If you have not already, please review it with the instructor.' % (self.member.offering.name()), url=self.get_absolute_url()) n.save()
def test_dst(self): """ Test news item in the ambiguous DST switchover """ instr = self.instructor n = NewsItem(user=instr, author=instr, source_app='foo', title='The Title', content='Content') n.save() c = Client() c.login_user(instr.userid) test_views(self, c, '', ['dashboard:index', 'news:news_list'], {}) n.published = datetime.datetime(2014, 11, 2, 1, 30, 0) # there are two of this time because of the DST transition n.save() test_views(self, c, '', ['dashboard:index', 'news:news_list'], {})
def bulk_email(request, unit_slug, semester): hiring_semester = get_object_or_404(HiringSemester, semester__name=semester, unit__in=request.units, unit__label=unit_slug) contracts = TAContract.objects.draft(hiring_semester) if request.method == 'POST': form = EmailForm(request.POST) if form.is_valid(): subject = form.cleaned_data['subject'] message = form.cleaned_data['message'] sender = form.cleaned_data['sender'] url = reverse('tacontracts:student_contract', kwargs={'semester': semester}) contract_ids = [ int(x) for x in request.POST.getlist('contracts[]') ] contracts = TAContract.objects.visible(hiring_semester)\ .filter(id__in=contract_ids) for contract in contracts: n = NewsItem(user=contract.person, source_app="tacontracts", title=subject, url=url, author=sender, content=message) n.save() e = EmailReceipt(contract=contract, content=n) e.save() messages.add_message(request, messages.SUCCESS, 'Email sent.') return _contracts_redirect(unit_slug, semester) else: form = EmailForm() return render( request, 'tacontracts/bulk_email.html', { 'unit_slug': unit_slug, 'semester': semester, 'contracts': contracts, 'form': form, })
def bulk_email(request, unit_slug, semester): hiring_semester = get_object_or_404(HiringSemester, semester__name=semester, unit__in=request.units, unit__label=unit_slug) contracts = TAContract.objects.draft(hiring_semester) if request.method == 'POST': form = EmailForm(request.POST) if form.is_valid(): subject = form.cleaned_data['subject'] message = form.cleaned_data['message'] sender = form.cleaned_data['sender'] url = reverse('tacontracts.views.student_contract', kwargs={'semester':semester}) contract_ids = [int(x) for x in request.POST.getlist('contracts[]')] contracts = TAContract.objects.visible(hiring_semester)\ .filter(id__in=contract_ids) for contract in contracts: n = NewsItem(user=contract.person, source_app="tacontracts", title=subject, url=url, author=sender, content=message) n.save() e = EmailReceipt(contract=contract, content=n) e.save() messages.add_message(request, messages.SUCCESS, u'Email sent.') return _contracts_redirect(unit_slug, semester) else: form = EmailForm() return render(request, 'tacontracts/bulk_email.html', { 'unit_slug':unit_slug, 'semester':semester, 'contracts':contracts, 'form':form, })
def save(self, entered_by, mark=None, newsitem=True, group=None, is_temporary=False): """Save the grade. entered_by must be one of: (1) the Person object of the person who entered the grade, (2) the userid of the person who entered the grade, (3) None ONLY if this was a result of a calculation (or for a temporary save that will be re-saved later) mark is a reference to the StudentActivityMark or GroupActivity mark, if that's where the grade came from newsitem controls the posting of a NewsItem for the student. """ if self.flag == "NOGR": # make sure "no grade" values have a zero: just in case the value is used in some other calc self.value = 0 super(NumericGrade, self).save() entered_by = get_entry_person(entered_by) if bool(mark) and not mark.id: raise ValueError("ActivityMark must be saved before calling setMark.") if entered_by: gh = GradeHistory(activity=self.activity, member=self.member, entered_by=entered_by, activity_status=self.activity.status, numeric_grade=self.value, grade_flag=self.flag, comment=self.comment, mark=mark, group=group) gh.save() else: assert (self.flag == 'CALC') or (is_temporary and self.flag=='NOGR') if self.activity.status == "RLS" and newsitem and self.flag not in ["NOGR", "CALC"]: # new grade assigned, generate news item only if the result is released n = NewsItem(user=self.member.person, author=None, course=self.activity.offering, source_app="grades", title="%s grade available" % (self.activity.name), content='A new grade for %s in %s is available.' % (self.activity.name, self.activity.offering.name()), url=self.activity.get_absolute_url()) n.save()
def submit(request, course_slug): person = get_object_or_404(Person, userid=request.user.username) course = get_object_or_404(CourseOffering, slug=course_slug) member = Member.objects.exclude(role='DROP').get(person=person, offering=course) is_staff = is_course_staff_by_slug(request, course_slug) span = course.group_span_activities() error_info = None name = request.POST.get('GroupName') if name: name = name[:30] #Check if group has a unique name if Group.objects.filter(name=name, courseoffering=course): error_info = "A group named \"%s\" already exists" % (name) messages.add_message(request, messages.ERROR, error_info) return HttpResponseRedirect( reverse('offering:groups:groupmanage', kwargs={'course_slug': course_slug})) #Check if the group name is empty, these two checks may need to be moved to forms later. if name == "": error_info = "Group name cannot be empty: please enter a group name." messages.add_message(request, messages.ERROR, error_info) return HttpResponseRedirect( reverse('offering:groups:groupmanage', kwargs={'course_slug': course_slug})) else: # find selected activities selected_act = [] activities = Activity.objects.filter(offering=course, group=True, deleted=False) if not is_staff: activities = activities.exclude(status='INVI') for activity in activities: activityForm = ActivityForm(request.POST, prefix=activity.slug) if activityForm.is_valid( ) and activityForm.cleaned_data['selected'] == True: selected_act.append(activity) # no selected activities: fail. if not selected_act: messages.add_message(request, messages.ERROR, "Group not created: no activities selected.") return HttpResponseRedirect( reverse('offering:groups:groupmanage', kwargs={'course_slug': course_slug})) # check groups_span_activities restriction if it's set if not span and not is_staff and len(selected_act) > 1: # students cannot violate groups_span_activities restriction, but instructors can messages.add_message( request, messages.ERROR, "Group not created: groups cannot last for more than one activity in this course." ) return HttpResponseRedirect( reverse('offering:groups:groupmanage', kwargs={'course_slug': course_slug})) groupForSemester = False #validate database integrity before saving anything. #If one student is in a group for an activity, he/she cannot be in another group for the same activity. if is_course_student_by_slug(request, course_slug): isStudentCreatedGroup = True studentList = [] studentList.append(member) elif is_course_staff_by_slug(request, course_slug): isStudentCreatedGroup = False studentList = [] students = Member.objects.select_related('person').filter( offering=course, role='STUD') for student in students: studentForm = StudentForm(request.POST, prefix=student.person.userid) if studentForm.is_valid( ) and studentForm.cleaned_data['selected'] == True: studentList.append(student) #Check if students has already in a group if _validateIntegrity(request, isStudentCreatedGroup, groupForSemester, course, studentList, selected_act) == False: return HttpResponseRedirect( reverse('offering:groups:groupmanage', kwargs={'course_slug': course_slug})) #No selected members,group creating will fail. if not studentList: messages.add_message(request, messages.ERROR, "Group not created: no members selected.") return HttpResponseRedirect( reverse('offering:groups:groupmanage', kwargs={'course_slug': course_slug})) group = Group(name=name, manager=member, courseoffering=course, groupForSemester=groupForSemester) group.save() #LOG EVENT# l = LogEntry(userid=request.user.username, description="created a new group %s for %s." % (group.name, course), related_object=group) l.save() if is_course_student_by_slug(request, course_slug): for activity in selected_act: groupMember = GroupMember(group=group, student=member, confirmed=True, activity_id=activity.id) groupMember.save() #LOG EVENT# l = LogEntry( userid=request.user.username, description= "automatically became a group member of %s for activity %s." % (group.name, groupMember.activity), related_object=groupMember) l.save() messages.add_message(request, messages.SUCCESS, 'Group Created') return HttpResponseRedirect( reverse('offering:groups:groupmanage', kwargs={'course_slug': course_slug})) elif is_course_staff_by_slug(request, course_slug): students = Member.objects.select_related('person').filter( offering=course, role='STUD') for student in students: studentForm = StudentForm(request.POST, prefix=student.person.userid) if studentForm.is_valid( ) and studentForm.cleaned_data['selected'] == True: for activity in selected_act: groupMember = GroupMember(group=group, student=student, confirmed=True, activity_id=activity.id) groupMember.save() #LOG EVENT# l = LogEntry( userid=request.user.username, description= "added %s as a group member to %s for activity %s." % (student.person.userid, group.name, groupMember.activity), related_object=groupMember) l.save() n = NewsItem(user=student.person, author=member.person, course=group.courseoffering, source_app="group", title="Added to Group", content="You have been added the group %s." % (group.name), url=reverse( 'offering:groups:groupmanage', kwargs={'course_slug': course.slug})) n.save() messages.add_message(request, messages.SUCCESS, 'Group Created') return HttpResponseRedirect( reverse('offering:groups:view_group', kwargs={ 'course_slug': course_slug, 'group_slug': group.slug })) else: return HttpResponseForbidden()
def submit(request, course_slug): person = get_object_or_404(Person,userid=request.user.username) course = get_object_or_404(CourseOffering, slug = course_slug) member = Member.objects.exclude(role='DROP').get(person=person, offering=course) error_info=None name = request.POST.get('GroupName') if name: name = name[:30] #Check if group has a unique name if Group.objects.filter(name=name,courseoffering=course): error_info="A group named \"%s\" already exists" % (name) messages.add_message(request, messages.ERROR, error_info) return HttpResponseRedirect(reverse('groups.views.groupmanage', kwargs={'course_slug': course_slug})) #Check if the group name is empty, these two checks may need to be moved to forms later. if name == "": error_info = "Group name cannot be empty: please enter a group name." messages.add_message(request, messages.ERROR, error_info) return HttpResponseRedirect(reverse('groups.views.groupmanage', kwargs={'course_slug': course_slug})) else: # find selected activities selected_act = [] activities = Activity.objects.filter(offering=course, group=True, deleted=False) if not is_course_staff_by_slug(request, course_slug): activities = activities.exclude(status='INVI') for activity in activities: activityForm = ActivityForm(request.POST, prefix=activity.slug) if activityForm.is_valid() and activityForm.cleaned_data['selected'] == True: selected_act.append(activity) # no selected activities: fail. if not selected_act: messages.add_message(request, messages.ERROR, "Group not created: no activities selected.") return HttpResponseRedirect(reverse('groups.views.groupmanage', kwargs={'course_slug': course_slug})) #groupForSemesterForm = GroupForSemesterForm(request.POST) #if groupForSemesterForm.is_valid(): # groupForSemester = groupForSemesterForm.cleaned_data['selected'] groupForSemester = False #validate database integrity before saving anything. #If one student is in a group for an activity, he/she cannot be in another group for the same activity. if is_course_student_by_slug(request, course_slug): isStudentCreatedGroup = True studentList = [] studentList.append(member) elif is_course_staff_by_slug(request, course_slug): isStudentCreatedGroup = False studentList = [] students = Member.objects.select_related('person').filter(offering = course, role = 'STUD') for student in students: studentForm = StudentForm(request.POST, prefix = student.person.userid) if studentForm.is_valid() and studentForm.cleaned_data['selected'] == True: studentList.append(student) #Check if students has already in a group if _validateIntegrity(request,isStudentCreatedGroup, groupForSemester, course, studentList, selected_act) == False: return HttpResponseRedirect(reverse('groups.views.groupmanage', kwargs={'course_slug': course_slug})) #No selected members,group creating will fail. if not studentList: messages.add_message(request, messages.ERROR, "Group not created: no members selected.") return HttpResponseRedirect(reverse('groups.views.groupmanage', kwargs={'course_slug': course_slug})) group = Group(name=name, manager=member, courseoffering=course, groupForSemester = groupForSemester) group.save() #LOG EVENT# l = LogEntry(userid=request.user.username, description="created a new group %s for %s." % (group.name, course), related_object=group ) l.save() if is_course_student_by_slug(request, course_slug): for activity in selected_act: groupMember = GroupMember(group=group, student=member, confirmed=True, activity=activity) groupMember.save() #LOG EVENT# l = LogEntry(userid=request.user.username, description="automatically became a group member of %s for activity %s." % (group.name, groupMember.activity), related_object=groupMember ) l.save() messages.add_message(request, messages.SUCCESS, 'Group Created') return HttpResponseRedirect(reverse('groups.views.groupmanage', kwargs={'course_slug': course_slug})) elif is_course_staff_by_slug(request, course_slug): students = Member.objects.select_related('person').filter(offering = course, role = 'STUD') for student in students: studentForm = StudentForm(request.POST, prefix = student.person.userid) if studentForm.is_valid() and studentForm.cleaned_data['selected'] == True: for activity in selected_act: groupMember = GroupMember(group=group, student=student, confirmed=True, activity=activity) groupMember.save() #LOG EVENT# l = LogEntry(userid=request.user.username, description="added %s as a group member to %s for activity %s." % (student.person.userid,group.name, groupMember.activity), related_object=groupMember ) l.save() n = NewsItem(user=student.person, author=member.person, course=group.courseoffering, source_app="group", title="Added to Group", content="You have been added the group %s." % (group.name), url=reverse('groups.views.groupmanage', kwargs={'course_slug':course.slug}) ) n.save() messages.add_message(request, messages.SUCCESS, 'Group Created') return HttpResponseRedirect(reverse('groups.views.view_group', kwargs={'course_slug': course_slug, 'group_slug': group.slug})) else: return HttpResponseForbidden()
def invite(request, course_slug, group_slug): #TODO need to validate the student who is invited, cannot be the invitor him/herself. course = get_object_or_404(CourseOffering, slug = course_slug) group = get_object_or_404(Group, courseoffering = course, slug = group_slug) person = get_object_or_404(Person, userid = request.user.username) invitor = get_object_or_404(Member, person = person, offering=course) error_info=None group_max = course.group_max() from django import forms class StudentReceiverForm(forms.Form): name = forms.CharField() if request.method == "POST": student_receiver_form = StudentReceiverForm(request.POST) #student_receiver_form.activate_addform_validation(course_slug,group_slug) if student_receiver_form.is_valid(): name = student_receiver_form.cleaned_data['name'] existing = GroupMember.objects.filter(group=group).values('student').order_by().distinct().count() if group_max and existing >= group_max: messages.add_message(request, messages.ERROR, 'Group already has %s members, which is the maximum.' % (group_max)) return HttpResponseRedirect(reverse('groups.views.groupmanage', kwargs={'course_slug': course_slug})) members = Member.objects.filter(person__userid = name, offering = course, role="STUD") if not members: messages.add_message(request, messages.ERROR, 'Could not find userid "%s".' % (name)) return HttpResponseRedirect(reverse('groups.views.groupmanage', kwargs={'course_slug': course_slug})) member = members[0] # find out if this person is already in a group gms = group.groupmember_set.all() all_act = all_activities(gms) existing_memb = GroupMember.objects.filter(student=member, activity__in=all_act) if GroupMember.objects.filter(student=member, group=group): messages.add_message(request, messages.ERROR, "%s is already in this group" % (member.person.userid)) elif existing_memb: error="%s is already in a group for %s" % (member.person.userid, ", ".join(m.activity.name for m in existing_memb)) messages.add_message(request, messages.ERROR, error) else: #member = Member.objects.get(person = member.person, offering = course) for invitorMembership in GroupMember.objects.filter(group = group, student = invitor): newGroupMember = GroupMember(group = group, student = member, activity = invitorMembership.activity, confirmed = False) newGroupMember.save(member.person) #LOG EVENT# l = LogEntry(userid=request.user.username, description="invited %s to join group %s for activity %s." % (newGroupMember.student.person.userid,group.name, newGroupMember.activity), related_object=newGroupMember ) l.save() n = NewsItem(user=member.person, author=person, course=group.courseoffering, source_app="group", title="Group Invitation", content="You have been invited to join group %s." % (group.name), url=reverse('groups.views.groupmanage', kwargs={'course_slug':course.slug}) ) n.save() messages.add_message(request, messages.SUCCESS, 'Your invitation to %s has been sent out.' % (member.person.name())) return HttpResponseRedirect(reverse('groups.views.groupmanage', kwargs={'course_slug': course_slug})) else: messages.add_message(request, messages.ERROR, "Invalid userid.") return HttpResponseRedirect(reverse('groups.views.groupmanage', kwargs={'course_slug': course_slug})) else: student_receiver_form = StudentReceiverForm() context = {'course': course, 'form': student_receiver_form} return render_to_response("groups/invite.html", context, context_instance=RequestContext(request))
def invite(request, course_slug, group_slug): #TODO need to validate the student who is invited, cannot be the invitor him/herself. course = get_object_or_404(CourseOffering, slug=course_slug) group = get_object_or_404(Group, courseoffering=course, slug=group_slug) person = get_object_or_404(Person, userid=request.user.username) invitor = get_object_or_404(Member, ~Q(role='DROP'), person=person, offering=course) error_info = None group_max = course.group_max() from django import forms class StudentReceiverForm(forms.Form): name = forms.CharField() if request.method == "POST": student_receiver_form = StudentReceiverForm(request.POST) #student_receiver_form.activate_addform_validation(course_slug,group_slug) if student_receiver_form.is_valid(): name = student_receiver_form.cleaned_data['name'] existing = GroupMember.objects.filter( group=group).values('student').order_by().distinct().count() if group_max and existing >= group_max: messages.add_message( request, messages.ERROR, 'Group already has %s members, which is the maximum.' % (group_max)) return HttpResponseRedirect( reverse('offering:groups:groupmanage', kwargs={'course_slug': course_slug})) members = Member.objects.filter(person__userid=name, offering=course, role="STUD") if not members: messages.add_message(request, messages.ERROR, 'Could not find userid "%s".' % (name)) return HttpResponseRedirect( reverse('offering:groups:groupmanage', kwargs={'course_slug': course_slug})) member = members[0] # find out if this person is already in a group gms = group.groupmember_set.all() all_act = all_activities(gms) existing_memb = GroupMember.objects.filter(student=member, activity__in=all_act) if GroupMember.objects.filter(student=member, group=group): messages.add_message( request, messages.ERROR, "%s is already in this group" % (member.person.userid)) elif existing_memb: error = "%s is already in a group for %s" % ( member.person.userid, ", ".join(m.activity.name for m in existing_memb)) messages.add_message(request, messages.ERROR, error) else: #member = Member.objects.get(person = member.person, offering = course) for invitorMembership in GroupMember.objects.filter( group=group, student=invitor): newGroupMember = GroupMember( group=group, student=member, activity=invitorMembership.activity, confirmed=False) newGroupMember.save(member.person) #LOG EVENT# l = LogEntry( userid=request.user.username, description= "invited %s to join group %s for activity %s." % (newGroupMember.student.person.userid, group.name, newGroupMember.activity), related_object=newGroupMember) l.save() n = NewsItem( user=member.person, author=person, course=group.courseoffering, source_app="group", title="Group Invitation", content="You have been invited to join group %s." % (group.name), url=reverse('offering:groups:groupmanage', kwargs={'course_slug': course.slug})) n.save() messages.add_message( request, messages.SUCCESS, 'Your invitation to %s has been sent out.' % (member.person.name())) return HttpResponseRedirect( reverse('offering:groups:groupmanage', kwargs={'course_slug': course_slug})) else: messages.add_message(request, messages.ERROR, "Invalid userid.") return HttpResponseRedirect( reverse('offering:groups:groupmanage', kwargs={'course_slug': course_slug})) else: student_receiver_form = StudentReceiverForm() context = {'course': course, 'form': student_receiver_form} return render(request, "groups/invite.html", context)