def deleteForm(self): """ Deletes all information relating to the form from the db. Also removes the response table """ dyn = DMH(form=self.form) dyn.deleteTable() self.form.delete() # Cascading Foreign Keys should take care of everything
def onSubmit(request): #Stores form metadata in the database. if request.is_ajax(): if request.method == 'POST': metadata = json.loads(request.body) fields = [] # truncating field lengths to the character limits specified title = metadata['title'][0:Form._meta.get_field('title').max_length] link_type = metadata['link_type'][0:Form._meta.get_field('link_type'). max_length] perms = metadata['perms'][0:Form._meta.get_field('perms').max_length] success_message = metadata['success_message'][ 0:Form._meta.get_field('success_message').max_length] success_url = metadata['success_url'][ 0:Form._meta.get_field('success_url').max_length] # Creating form form = Form.objects.create(title=title, description=metadata['desc'], created_by=request.user, link_type=link_type, link_id=int(metadata['link_id']), anonymous=metadata['anonymous'], perms=perms, success_message=success_message, success_url=success_url) # Inserting pages for page in metadata['pages']: new_page = Page.objects.create(form=form, seq=int(page['seq'])) # inserting sections for section in page['sections']: new_section = Section.objects.create( page=new_page, title=section['data']['question_text'], description=section['data']['help_text'], seq=int(section['data']['seq'])) # inserting fields for field in section['fields']: if 'required' in field['data'] and field['data'][ 'required'] == 'checked': is_required = True else: is_required = False new_field = Field.objects.create( form=form, section=new_section, field_type=field['data']['field_type'], seq=int(field['data']['seq']), label=field['data']['question_text'], help_text=field['data']['help_text'], required=is_required) fields.append((new_field.id, new_field.field_type)) # inserting other attributes, if any for atype, aval in field['data']['attrs'].items(): new_attr = Attribute.objects.create(field=new_field, attr_type=atype, value=aval) dynH = DMH(form=form, fields=fields) dynH.createTable() return HttpResponse('OK')
def onModify(request): """ Handles form modifications """ if request.is_ajax(): if request.method == 'POST': metadata = json.loads(request.body) try: form = Form.objects.get(id=int(metadata['form_id'])) except: raise ESPError('Form %s not found' % metadata['form_id'], log=False) dmh = DMH(form=form) link_models_list = [ ] # Stores a cache of link models that should not be removed # Populating the old fields list dmh._getModelFieldList() # NOT updating 'anonymous' form.__dict__.update(title=metadata['title'], description=metadata['desc'], perms=metadata['perms'], success_message=metadata['success_message'], success_url=metadata['success_url']) form.save() # Check if only_fkey links have changed if form.link_type != metadata['link_type']: dmh.change_only_fkey(form, form.link_type, metadata['link_type'], link_id) curr_keys = {'pages': [], 'sections': [], 'fields': []} old_pages = Page.objects.filter(form=form) old_sections = Section.objects.filter(page__in=old_pages) old_fields = Field.objects.filter(form=form) for page in metadata['pages']: curr_page = get_new_or_altered_obj(Page, page['parent_id'], form=form, seq=int(page['seq'])) curr_keys['pages'].append(curr_page.id) for section in page['sections']: curr_sect = get_new_or_altered_obj( Section, section['data']['parent_id'], page=curr_page, title=section['data']['question_text'], description=section['data']['help_text'], seq=int(section['data']['seq'])) curr_keys['sections'].append(curr_sect.id) for field in section['fields']: (curr_field, old_field, field_created) = get_or_create_altered_obj( Field, field['data']['parent_id'], form=form, section=curr_sect, field_type=field['data']['field_type'], seq=int(field['data']['seq']), label=field['data']['question_text'], help_text=field['data']['help_text'], required=field['data']['required']) if field_created: # Check for link field if cf_cache.isLinkField(curr_field.field_type): dmh.addLinkFieldColumn(curr_field) else: dmh.addField(curr_field) elif not cf_cache.isLinkField(curr_field.field_type): dmh.updateField(curr_field, old_field) # Store a reference to the linked model so that we don't drop it from the table. if cf_cache.isLinkField(curr_field.field_type): model_cls = cf_cache.modelForLinkField( curr_field.field_type) if model_cls.__name__ not in link_models_list: link_models_list.append(model_cls.__name__) for atype, aval in field['data']['attrs'].items(): curr_field.set_attribute(atype, aval) curr_keys['fields'].append(curr_field.id) del_fields = old_fields.exclude(id__in=curr_keys['fields']) for df in del_fields: # Check for link fields if cf_cache.isLinkField(df.field_type): model_cls = cf_cache.modelForLinkField(df.field_type) if model_cls.__name__ not in link_models_list: # This column needs to be dropped dmh.removeLinkField(df) else: dmh.removeField(df) del_fields.delete() old_sections.exclude(id__in=curr_keys['sections']).delete() old_pages.exclude(id__in=curr_keys['pages']).delete() return HttpResponse('OK')
def getResponseData(self, form): """ Returns the response data for this form, along with the questions """ dmh = DMH(form=form) dyn = dmh.createDynModel() response_data = {'questions': [], 'answers': []} responses = dyn.objects.all().order_by('id').values() fields = Field.objects.filter(form=form).order_by('section__page__seq', 'section__seq', 'seq').values('id', 'field_type', 'label') # Let's first do a bit of introspection to figure out # what the linked models are, and what values need to be added to the # response data from these linked models. # And since we're already iterating over fields, # let's also set the questions in the process. add_fields = {} # Add in the user column if form is not anonymous if not form.anonymous: response_data['questions'].append(['user_id', 'User', 'fk']) # Add in the column for link fields, if any if form.link_type != "-1": only_fkey_model = cf_cache.only_fkey_models[form.link_type] response_data['questions'].append(["link_%s_id" % only_fkey_model.__name__, form.link_type, 'fk']) else: only_fkey_model = None for field in fields: # I'll do a lot of merging here later qname = 'question_%d' % field['id'] ftype = field['field_type'] if cf_cache.isLinkField(ftype): # Let's grab the model first model = cf_cache.modelForLinkField(ftype) # Now let's see what fields need to be set add_fields[qname] = [model, cf_cache.getLinkFieldData(ftype)['model_field']] response_data['questions'].append([qname, field['label'], ftype]) # Include this field only if it isn't a dummy field elif generic_fields[ftype]['typeMap'] is not DummyField: response_data['questions'].append([qname, field['label'], ftype]) # Now let's set up the responses for response in responses: link_instances_cache={} # Add in user if form is not anonymous if not form.anonymous: response['user_id'] = unicode(response['user_id']) # Add in links if only_fkey_model is not None: if only_fkey_model.objects.filter(pk=response["link_%s_id" % only_fkey_model.__name__]).exists(): inst = only_fkey_model.objects.get(pk=response["link_%s_id" % only_fkey_model.__name__]) else: inst = None response["link_%s_id" % only_fkey_model.__name__] = unicode(inst) # Now, put in the additional fields in response for qname, data in add_fields.items(): if data[0].__name__ not in link_instances_cache: if data[0].objects.filter(pk=response["link_%s_id" % data[0].__name__]).exists(): link_instances_cache[data[0].__name__] = data[0].objects.get(pk=response["link_%s_id" % data[0].__name__]) else: link_instances_cache[data[0].__name__] = None if cf_cache.isCompoundLinkField(data[0], data[1]): if link_instances_cache[data[0].__name__] is None: response[qname] = [] else: response[qname] = [link_instances_cache[data[0].__name__].__dict__[x] for x in cf_cache.getCompoundLinkFields(data[0], data[1])] else: if link_instances_cache[data[0].__name__] is None: response[qname]='' else: response[qname] = link_instances_cache[data[0].__name__].__dict__[data[1]] # Add responses to response_data response_data['answers'].extend(responses) return response_data
def done(self, form_list, **kwargs): data = {} dyn = DMH(form=self.form) dynModel = dyn.createDynModel() fields = dict(dyn.fields) link_models_cache = {} # Plonking in user_id if the form is non-anonymous if not self.form.anonymous: data['user'] = self.curr_request.user # Populating data with the values that need to be inserted for form in form_list: for k,v in form.cleaned_data.items(): # Check for only_fkey link models first if k.split('_')[1] in cf_cache.only_fkey_models: data[k] = v continue field_id = int(k.split("_")[1]) ftype = fields[field_id] # Now check for link fields if cf_cache.isLinkField(ftype): model = cf_cache.modelForLinkField(ftype) if model.__name__ not in link_models_cache: link_models_cache[model.__name__] = {'model': model, 'data': {}} pre_instance = self.form_handler.getInstanceForLinkField(k, model) if pre_instance is not None: link_models_cache[model.__name__]['instance'] = pre_instance else: link_models_cache[model.__name__]['instance'] = getattr(model, 'cf_link_instance')(self.curr_request) ftype_parts = ftype.split('_') if len(ftype_parts) > 1 and cf_cache.isCompoundLinkField(model, '_'.join(ftype_parts[1:])): # Try to match a model field to the last part of the key we have. partial_field_name = str(field_id).join(k.split(str(field_id))[1:]).lstrip('_') target_fields = cf_cache.getCompoundLinkFields(model, '_'.join(ftype_parts[1:])) for f in target_fields: if f.endswith(partial_field_name): model_field = f break else: model_field = cf_cache.getLinkFieldData(ftype)['model_field'] link_models_cache[model.__name__]['data'].update({model_field: v}) else: data[k] = v # Create/update instances corresponding to link fields # Also, populate 'data' with foreign-keys that need to be inserted into the response table for k,v in link_models_cache.items(): if v['instance'] is not None: # TODO-> the following update won't work for fk fields. v['instance'].__dict__.update(v['data']) v['instance'].save() curr_instance = v['instance'] else: try: new_instance = v['model'].objects.create(**v['data']) except: # show some error message pass if v['instance'] is not None: data['link_%s' % v['model'].__name__] = v['instance'] # Saving response initial_keys = data.keys() for key in initial_keys: # Check that we didn't already handle this value as a linked field if key.split('_')[0] in cf_cache.link_fields: del data[key] # Check that this value didn't come from a dummy field if key.split('_')[0] == 'question' and generic_fields[fields[int(key.split('_')[1])]]['typeMap'] == DummyField: del data[key] dynModel.objects.create(**data) return HttpResponseRedirect('/customforms/success/%d/' % self.form.id)
def getResponseData(self, form): """ Returns the response data for this form, along with the questions """ dmh = DMH(form=form) dyn = dmh.createDynModel() response_data = {'questions': [], 'answers': []} responses = dyn.objects.all().order_by('id').values() fields = Field.objects.filter(form=form).order_by('section__page__seq', 'section__seq', 'seq').values('id', 'field_type', 'label') # Let's first do a bit of introspection to figure out # what the linked models are, and what values need to be added to the # response data from these linked models. # And since we're already iterating over fields, # let's also set the questions in the process. add_fields = {} # Add in the user column if form is not anonymous if not form.anonymous: response_data['questions'].append(['user_id', 'User ID', 'fk']) response_data['questions'].append(['user_display', 'User', 'textField']) response_data['questions'].append(['user_email', 'User e-mail', 'textField']) response_data['questions'].append(['username', 'Username', 'textField']) # Add in the column for link fields, if any if form.link_type != "-1": only_fkey_model = cf_cache.only_fkey_models[form.link_type] response_data['questions'].append(["link_%s_id" % only_fkey_model.__name__, form.link_type, 'fk']) else: only_fkey_model = None for field in fields: # I'll do a lot of merging here later qname = 'question_%d' % field['id'] ftype = field['field_type'] if cf_cache.isLinkField(ftype): # Let's grab the model first model = cf_cache.modelForLinkField(ftype) # Now let's see what fields need to be set add_fields[qname] = [model, cf_cache.getLinkFieldData(ftype)['model_field']] response_data['questions'].append([qname, field['label'], ftype]) # Include this field only if it isn't a dummy field elif generic_fields[ftype]['typeMap'] is not DummyField: response_data['questions'].append([qname, field['label'], ftype]) users = ESPUser.objects.in_bulk(map(lambda response: response['user_id'], responses)) # Now let's set up the responses for response in responses: link_instances_cache={} # Add in user if form is not anonymous if not form.anonymous: user = users[response['user_id']] response['user_id'] = unicode(response['user_id']) response['user_display'] = user.name() response['user_email'] = user.email response['username'] = user.username # Add in links if only_fkey_model is not None: if only_fkey_model.objects.filter(pk=response["link_%s_id" % only_fkey_model.__name__]).exists(): inst = only_fkey_model.objects.get(pk=response["link_%s_id" % only_fkey_model.__name__]) else: inst = None response["link_%s_id" % only_fkey_model.__name__] = unicode(inst) # Now, put in the additional fields in response for qname, data in add_fields.items(): if data[0].__name__ not in link_instances_cache: if data[0].objects.filter(pk=response["link_%s_id" % data[0].__name__]).exists(): link_instances_cache[data[0].__name__] = data[0].objects.get(pk=response["link_%s_id" % data[0].__name__]) else: link_instances_cache[data[0].__name__] = None if cf_cache.isCompoundLinkField(data[0], data[1]): if link_instances_cache[data[0].__name__] is None: response[qname] = [] else: response[qname] = [link_instances_cache[data[0].__name__].__dict__[x] for x in cf_cache.getCompoundLinkFields(data[0], data[1])] else: if link_instances_cache[data[0].__name__] is None: response[qname]='' else: response[qname] = link_instances_cache[data[0].__name__].__dict__[data[1]] # Add responses to response_data response_data['answers'].extend(responses) return response_data