def struct_officers(request, id, year=None): ''' Obtain officers for district or MD ''' # check if permitted to edit this struct edit, response = permissions.can_edit_dist(request.user, id) if not edit: return render_to_response('md_directory/not_auth.html', {'response': response}) if not year: year = get_current_year() #check if year is an int try: year = int(year) except: return HttpResponse("%d is not a valid year" % year) try: id = int(id) except: # Could not obtain instance, report bad ID return HttpResponse( "%d is an invalid district or multiple district id" % id) struct = models.Struct.objects.get(id=id) md = struct.type_id == 1 titles = {0: [5, 7, 8, 9, 10], 1: [11, 13, 14, 15]}[md] #obtain queryset to limit chairs table = [] for t in titles: q = models.StructOfficer.objects.filter(struct=id).filter( year=year).filter(office=str(t)) if q: q = q[0] d = { 'office': q.office, 'member': q.member, 'email': q.email, 'id': t } else: d = { 'office': models.OfficerTitle.objects.get(pk=str(t)), 'member': 'No office holder', 'email': '', 'id': t } table.append(d) return render_to_response('md_directory/struct_officers.html', { 'table': table, 'name': struct.__unicode__(), 'year': year, 'id': id })
def struct_chairs_mentors(request, id, year=None, off_type="chair"): # check if permitted to edit this struct edit, response = permissions.can_edit_dist(request.user, id) if not edit: return render_to_response('md_directory/not_auth.html', {'response': response}) if not year: year = get_current_year() #check if year is an int try: year = int(year) except: return HttpResponse("%d is not a valid year" % year) try: id = int(id) except: # Could not obtain instance, report bad ID return HttpResponse( "%d is an invalid district or multiple district id" % id) types = {'chair': models.StructChair, 'mentor': models.Mentor} struct = models.Struct.objects.get(id=id) md = struct.type_id == 1 if off_type not in types: return HttpResponse( "%s is an invalid type of district or multiple district officer" % off_type) #obtain queryset to limit members q = types[off_type].objects.filter(struct=id).filter(year=year) table = [] for obj in q: table.append({'member': obj.member, 'email': obj.email, 'id': obj.id}) if hasattr(obj, 'office'): table[-1]['office'] = obj.office return render_to_response( 'md_directory/struct_chair_mentor.html', { 'table': table, 'name': struct.__unicode__(), 'year': year, 'id': id, 'off_type': off_type })
def s_mc_lobs_do_r_z_c_m(request, obj, id=0): ''' Edit the details of a struct, zone, club or region ''' from django.forms import ModelForm print 'in s_mc_lobs_do_r_z_c_m' # check that obj is from the right list if obj not in [ 'struct', 'merch_centre', 'brightsight', 'dist_office', 'region', 'zone', 'club', 'member' ]: return HttpResponse("%s is an invalid type" % obj) id = int(id) # get the model from the supplied obj model = get_model(obj) edit = True if id != 0: # try: if 1: i = model.objects.get(pk=id) # Determine if permission is available to edit this particular item: if obj == 'member': # Determine if club perms available edit, response = permissions.can_edit_club( request.user, i.club_id, obj) elif obj == 'club': # club user may edit their own club # Determine if club perms available edit, response = permissions.can_edit_club(request.user, i.id) elif obj == 'struct': # Determine if struct perms available edit, response = permissions.can_edit_dist(request.user, i.id) elif obj in [ 'merch_centre', 'brightsight', 'dist_office', 'region', 'zone' ]: # Determine if struct perms available edit, response = permissions.can_edit_dist( request.user, i.struct_id, obj) elif obj in ['merch_centre']: # Determine if struct perms available edit, response = permissions.can_edit_md( request.user, i.struct_id, obj) # check if one of the fields is from a list that should be limited by struct for a in ['zone', 'region', 'parent']: if hasattr(model, a) and hasattr(i, 'struct'): getattr(model, a).field.rel.limit_choices_to = { 'struct': i.struct } # except: # if not HANDLE_EXC: raise # # Could not obtain instance, report bad id # return HttpResponse("%s is an invalid %s id" % (id, obj)) else: i = None # Only dist users or above can add new clubs p = request.user.get_profile() if obj == 'club' and p.is_club: edit, response = ( False, 'You do not have the necessary permissions to add new clubs to the system.' ) if not edit: return render_to_response('md_directory/not_auth.html', {'response': response}) # for forms which carry an id, if an id of 0 is input, calculate the next negative id to use import copy post = copy.copy(request.POST) if ('id' in post) and (post['id'] == '0'): neg_id = str(int(model.objects.all().order_by('id')[0].id) - 1) post['id'] = neg_id # dict to hold preset form values, preset for various permission related reasons preset = {} class Form(ModelForm): class Meta: model = get_model(obj) exclude = [] # if there is a real instance, exclude id as this should not be changed if id: exclude.append('id') # a dict keyed by objects which need altering, with the length as the value field_names = model._meta.get_all_field_names() wid = { 'website': 60, 'facebook': 60, 'email': 50, 'meet_time': 50, 'home_ph': 50, 'cell_ph': 50, 'bus_ph': 50, 'fax': 50, 'tel': 30, 'hours': 60, 'manager_email': 50, 'manager_cell_ph': 50 } for n in range(1, 6): wid['add%d' % n] = 40 wid['postal%d' % n] = 40 widgets = {} for w in wid.keys(): if w in field_names: widgets[w] = forms.TextInput(attrs={'size': wid[w]}) # permission limitations p = request.user.get_profile() # if there is a club field, limit to a specific club if a club user, or clubs in the dist if a dist user if ('club' in field_names) and (obj == 'member'): if p.is_club: # exclude club dropdown and set as a preset exclude.append('club') preset['club_id'] = p.club_id if p.is_dist: # limit clubs to those in the district model.club.field.rel.limit_choices_to = { 'struct': p.struct } # if there is a zone field, limit to a specific zone if a club user, or zones in the dist if a dist user if ('zone' in field_names) and (obj == 'club'): if p.is_club: # exclude zone dropdown and set as a preset exclude.append('zone') preset['zone_id'] = model.objects.get( pk=int(p.club_id)).zone_id if p.is_dist: # limit zones to those in the district model.zone.field.rel.limit_choices_to = { 'struct': p.struct } if ('struct' in field_names) and (obj in [ 'club', 'zone', 'region', 'dist_office' ]): if p.is_club or p.is_dist: # exclude zone dropdown and set as a preset exclude.append('struct') if p.is_club: preset['struct_id'] = model.objects.get( pk=int(p.club_id)).struct_id else: preset['struct_id'] = p.struct_id # don't permit dist user to change MD of dist if ('md' in field_names) and (obj in ['struct']): if p.is_dist: # exclude zone dropdown and set as a preset exclude.append('md') preset['md'] = model.objects.get(pk=int(p.struct_id)).md if request.method == 'POST': form = Form(post, instance=i) old = copy.copy(i) if form.is_valid(): # All validation rules pass table = [] # How to determine the name of the object. The default of 'name' is used if no specific match is found if obj in ['member']: name = '%(first_name)s %(last_name)s' % form.cleaned_data elif obj in ['dist_office', 'brightsight']: name = obj else: name = '%(name)s' % form.cleaned_data if i: # Provide differing covering blurb depending on whether changes were made if form.has_changed(): blurb = 'The following details of %s have been changed:' % name else: blurb = 'No changes were made to the details of %s' % name # Generate a list of changes made for c in form.changed_data: try: old_val = getattr(old, c) except ObjectDoesNotExist: old_val = None # append label, old and new value to a list for table rendering table.append( (form.fields[c].label, old_val, form.cleaned_data[c])) # Store changes in DB and provide render confirmation page. else: blurb = '%s has been added to the system' % name # add presets to form save_obj = form.save(commit=False) for k, v in preset.items(): setattr(save_obj, k, v) save_obj.save() # TODO: replace with confirmation and main menu return return index(request, blurb, table) else: # Not a POST, build an initial form, using instance if there is one form = Form(instance=i) return render_to_response('md_directory/s_mc_lobs_do_r_z_c_m.html', { 'form': form, 'id': id, 'type': obj, 'title': get_label(obj) })
def region_zone_chair_edit(request, id, year, obj): ''' Edit the details of the chair of a region or zone ''' # get the model from the supplied obj model = getattr(models, obj.capitalize()) model_chair = getattr(models, '%sChair' % obj.capitalize()) # Set i to DB instance if an id is supplied, No otherwise try: item = model.objects.get(pk=id) except: # Could not obtain instance, report bad ID return HttpResponse("%s is an invalid %s" % (id, obj)) if not year: year = get_current_year() #check if year is an int try: year = int(year) except: return HttpResponse("%d is not a valid year" % year) # check that obj is from the right list if obj not in ['region', 'zone']: return HttpResponse("%s is an invalid type" % obj) # check if permitted to edit this zone or region edit, response = permissions.can_edit_dist(request.user, item.struct_id, obj) if not edit: return render_to_response('md_directory/not_auth.html', {'response': response}) # obtain instance i = model_chair.objects.filter(year=str(year)).filter(parent=id) if i: i = i[0] else: i = None # limit members to those from the item's district # Temporarily disabled to allow all members to be displayed - # as with other areas, complicated queries sufficient to handle # merging tables aren't justified by the expected lifespan of this app # limit = {'club__struct': item.struct_id} limit = {} # generate a drop-down list of initials and a dict to match the selected number against to get the correct initial from string import ascii_uppercase inits = [(n, j) for n, j in enumerate(ascii_uppercase)] init_dict = dict([(v, k) for k, v in inits]) # if this is a POST, an initial will have been supplied if request.method == 'POST': # get the character submitted as the initial init = inits[int(request.POST['init'])][1] # determine if an initial was submitted which differs to the initial of the names in the member list if init != str(request.POST['member']).upper(): # set new initial for the form initial = init else: # set the initial to what it currently is, as a new one hasn't been chosen initial = str(request.POST['member']).upper() else: # not a post, determine what initial should initially be if i: # there is an instance, use its initial initial = str(i.member.last_name[0]).upper() else: # no instance, use a default initial = 'A' # refine member limit to use only the initial and apply the limit limit['last_name__istartswith'] = initial model_chair.member.field.rel.limit_choices_to = limit # A form to choose the initial. Applies a JS function if it is changed to prevent the need for a seperate submit button class InitForm(forms.Form): init = forms.ChoiceField( choices=inits, initial=ascii_uppercase[0], widget=forms.Select(attrs={"onchange": "form_initial_submit()"})) from django.forms import ModelForm class Form(ModelForm): class Meta: model = getattr(models, '%sChair' % obj.capitalize()) fields = ['member', 'email'] if request.method == 'POST': form = Form(request.POST, instance=i) if form.is_valid(): # All validation rules pass if i: form.save() else: # no instance, add a new item o = model_chair(parent=item, year=year, member=form.cleaned_data['member']) o.save() return redirect('/%s/chair/' % obj) else: # Not a POST, build an initial form, using instance if there is one form = Form(instance=i) # create the init form, supplying the initial to use initform = InitForm({'init': init_dict[initial]}) context = { 'form': form, 'year': year, 'id': id, 'name': item.__unicode__(), 'initform': initform, 'type': obj } return render_to_response('md_directory/zone_region_chair.html', context)
def struct_officeholder_edit(request, struct_id, year, office_id=None, office_type='chair', dg=False): from django.forms import ModelForm # check if permitted to edit this struct edit, response = permissions.can_edit_dist(request.user, struct_id) if not edit: return render_to_response('md_directory/not_auth.html', {'response': response}) model_dict = { 'chair': models.StructChair, 'officer': models.StructOfficer, 'mentor': models.Mentor } if office_type not in model_dict.keys(): return HttpResponse('%s is not a valid office_type' % office_type) model = model_dict[office_type] if not year: year = get_current_year() #check if year is an int try: year = int(year) except: return HttpResponse("%d is not a valid year" % year) try: struct = models.Struct.objects.get(pk=struct_id) except: # Could not obtain instance, report bad ID return HttpResponse("%s is an invalid struct id" % struct_id) #only limit members if not an md from django.db.models import Q # Temporary removal to allow all members to be picked, as work-around # for club merging table requiring a more complicated Q field # than the expected short-term life span of this app can justify limit = Q() # if (struct.type_id == 1) or year < (get_current_year()): # limit = Q() # else: # limit = (Q(club__struct=struct_id)|Q(club=None)) # exclude passed away people if current year if year == get_current_year(): limit = limit & Q(deceased_b=False) # Set i to DB instance if an id is supplied, No otherwise if office_id: try: i = model.objects.filter(year=str(year)).filter(struct=struct) if office_type in ['chair', 'mentor']: i = i.filter(id=office_id) else: i = i.filter(office=office_id) try: i = i[0] except: i = None except: # Could not obtain instance, report bad ID return HttpResponse("%s is an invalid id" % office_id) else: i = None from string import ascii_uppercase inits = [(n, j) for n, j in enumerate(ascii_uppercase)] init_dict = dict([(v, k) for k, v in inits]) if request.method == 'POST': init = inits[int(request.POST['init'])][1] if init != str(request.POST['member']).upper(): initial = init else: initial = str(request.POST['member']).upper() else: if i and i.member: initial = str(i.member.last_name[0]).upper() else: initial = 'A' limit = limit & Q(last_name__istartswith=initial) model.member.field.rel.limit_choices_to = limit init_data = {'init': init_dict[initial]} class InitForm(forms.Form): init = forms.ChoiceField( choices=inits, initial=ascii_uppercase[0], widget=forms.Select(attrs={"onchange": "form_initial_submit()"})) # Create the form class. class Form(ModelForm): class Meta: model = model_dict[office_type] fields = [] if office_type in ['chair']: fields.append('office') fields.append('committee_members') widgets = { 'office': forms.TextInput(attrs={'size': 100}), 'committee_members': forms.TextInput(attrs={'size': 100}) } fields.extend(['member', 'email']) if office_type in ['officer']: title = models.OfficerTitle.objects.get(id=office_id) else: title = '' if request.method == 'POST': # if id exists, use it to retrieve the data form = Form(request.POST, instance=i) if form.is_valid(): # All validation rules pass if i: form.save() else: if office_type in ['mentor']: obj = model(struct_id=struct_id, year=year, member=form.cleaned_data['member'], email=form.cleaned_data['email']) elif office_type in ['chair']: office = office = form.cleaned_data['office'] obj = model(struct_id=struct_id, year=year, member=form.cleaned_data['member'], email=form.cleaned_data['email'], office=office, committee_members=form. cleaned_data['committee_members']) else: office = title obj = model(struct_id=struct_id, year=year, member=form.cleaned_data['member'], email=form.cleaned_data['email'], office=office, end_month=12) obj.save() if dg: return redirect('/struct/dgs/%s/' % (struct_id)) return redirect('/struct/%ss/%d/%s/' % (office_type, year, struct_id)) else: # Not a POST, build an initial form, using id if there is one form = Form(instance=i) initform = InitForm(init_data) context = { 'form': form, 'struct_id': struct_id, 'year': year, 'office_id': office_id, 'name': struct, 'office_type': office_type, 'initform': initform } if dg: context['office_type'] = 'dg' if office_type in ['officer']: context['title'] = title return render_to_response('md_directory/struct_officeholder.html', context)
def club_zones(request, struct_id, group_type='zone'): ''' Pick club zones or zone regions for each club or zone in the district group_type can either be "zone" or "region" ''' import django.forms # check if permitted to edit this struct edit, response = permissions.can_edit_dist(request.user, struct_id) if not edit: return render_to_response('md_directory/not_auth.html', {'response': response}) base_types = {'zone': 'club', 'region': 'zone'} if group_type not in base_types.keys(): return HttpResponse("%s is an invalid group type" % group_type) group_model = getattr(models, group_type.capitalize()) base_type = base_types[group_type] base_model = getattr(models, base_type.capitalize()) try: struct_id = int(struct_id) except: # Could not obtain instance, report bad ID return HttpResponse("%s is an invalid struct id" % struct_id) # obtain list of zones/regions for the club/zone group_items = [(z.id, z.__unicode__()) for z in group_model.objects.filter(struct=struct_id)] group_items.sort() # obtain a list of clubs/zones objs = base_model.objects.filter(struct=struct_id) if base_type == 'club': objs = objs.filter(closed_b=False) base_items = [(c.id, c.__unicode__()) for c in objs] base_items.sort(key=lambda s: s[1]) #create form to hold zones class GroupForm(django.forms.Form): def __init__(self, base_id, group_list, *args, **kwargs): super(GroupForm, self).__init__(*args, **kwargs) base = base_model.objects.get(pk=base_id) self.base = base.__unicode__() try: ini_group = getattr(base, '%s_id' % group_type) except: ini_group = 0 # create club and zone fields self.fields['group'] = forms.ChoiceField(choices=group_list, required=None, initial=ini_group) if base_type == 'zone': # add in next years zone chair zc = models.ZoneChair.objects.filter(parent=base_id).get( year=2015).member self.member = zc def clean_member(self): data = self.cleaned_data['group'] # ensure members set to 0 are changed to None for DB insertion try: if int(data) == 0: data = None except: pass return data def get_form_list(base_items, POST=None): ''' Return a list of GroupForms, one for each club ''' l = [] for c_id, name in base_items: if POST: # if this is a POSTed form, use the POST data in the form data = {'%d-group' % c_id: int(POST['%d-group' % c_id])} else: data = None l.append(GroupForm(c_id, group_items, data=data, prefix=str(c_id))) return l if request.method == 'POST': form_list = get_form_list(base_items, request.POST) # check that all forms are validaed if all(form.is_valid() for form in form_list): # Store changes in DB and render confirmation page. changes = [] for n, (t, name) in enumerate(base_items): form = form_list[n] if form.has_changed(): base = base_model.objects.get(pk=t) setattr(base, '%s_id' % group_type, int(form.cleaned_data['group'])) base.save() # TODO: temp measure - going back to club finder # return render_to_response('md_directory/confirmation_officers.html', {'changes':changes, 'name':name}) return redirect('/') else: # Not a POST, build an initial form form_list = get_form_list(base_items) # base on club_officers.html return render_to_response( 'md_directory/struct_zones.html', { 'form_list': form_list, 'name': models.Struct.objects.get(pk=struct_id), 'base_type': base_type, 'group_type': group_type, 'id': struct_id })