Exemplo n.º 1
0
 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
Exemplo n.º 2
0
 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
Exemplo n.º 3
0
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')
Exemplo n.º 4
0
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')
Exemplo n.º 5
0
    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
Exemplo n.º 6
0
    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)
Exemplo n.º 7
0
    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
Exemplo n.º 8
0
    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)