Example #1
0
    def save(self, collection=None):
        """    
        Saves the validated, cleaned form data. If a submission already exists,
        the new data will be merged over the old data.
        """

        # TODO: think about adding an "overwrite" argument to this function, default of False,
        # which will determine if an error should be thrown if the submission object already
        # exists, or if we should trust the data and overwrite the previous submission.

        # If there is no submission object, then this should just be a normal
        # Django form.  No need to call the save method, so we will raise an exception
        if not hasattr(self, 'submission'):
            raise LookupError(
                "There is no submission object.  Are your creating the form with 'retrun_class=True'? If so, no need to call save."
            )

        if not self.cleaned_data:
            raise LookupError(
                "The is_valid() method must be called before saving a form")

        # Slightly evil, do type checking to see if submission is a Submission object or string
        # If Submission object is a slug
        if isinstance(self.submission, str) or isinstance(
                self.submission, unicode):
            submission_slug = self.submission

            # Get or create the object
            self.submission, was_created = Submission.objects.get_or_create(
                slug=submission_slug, collection=collection)

        # Otherwise it should be a submission model object, if not raise
        elif not isinstance(self.submission, Submission):
            raise AttributeError(
                'Submission %s is not a valid submission object.' %
                self.submission)

        # We now have a submission object, so let's update the last_modified field
        self.submission.last_modified = datetime.datetime.now()
        self.submission.save()

        # Get the existing answers
        answers = Answer.objects.select_related('submission', 'data_from',
                                                'field').filter(
                                                    data_form__slug=self.slug,
                                                    submission=self.submission)

        # Get the fields from the form post
        field_keys = []
        for key in self.fields:
            # Mangle the key into the DB form, then get the right Field
            field_keys.append(_field_for_db(key))

        # Get all fields that pertian to this dataform (from db)
        fields_from_db = self.query_data['field_query']

        # Check for fields that aren't in the database and create a list of them
        fields_to_insert = []
        for field in fields_from_db:
            has_answer = filter(lambda a: a.field.slug == field.slug, answers)
            if has_answer:
                continue
            else:
                fields_to_insert.append(field)

        # For these new fields, create answer objects for insertion, if any
        if fields_to_insert:
            new_answers = []
            for field in fields_to_insert:
                # save the answer only if the field is in the form POST
                if field.slug in field_keys:
                    # Create a new answer object
                    answer = Answer()
                    answer.submission = self.submission
                    answer.data_form = self.query_data['dataform_query']
                    answer.field = field
                    new_answers.append(answer)

            # Insert the new objects, if any
            if new_answers:
                insert_many(new_answers)

            # Get Answers again so that we have the pks if we had answers that were inserted
            answers = (Answer.objects.select_related(
                'submission', 'data_from',
                'field').filter(data_form__slug=self.slug,
                                submission=self.submission))

        # Get All possible choices from form models dict
        choices = Choice.objects.all()

        # Setup answer list so we can do a bulk update
        answer_objects = []

        # We know answers exist now, so update them if needed.
        for answer in answers:

            # Delete the choices so we can re-insert
            AnswerChoice.objects.filter(answer=answer).delete()

            answer_obj, choice_relations = self._prepare_answer(
                answer, choices)
            answer_objects.append(answer_obj)

            # If there are choices, do mass insert on them for each answer.
            if choice_relations:
                answer_choices = []
                for choice in choice_relations:
                    answer_choice = AnswerChoice()
                    answer_choice.answer = answer
                    answer_choice.choice = choice
                    answer_choices.append(answer_choice)

                insert_many(answer_choices)

        # Update the answers
        update_many(answer_objects, fields=['value'])

        # Return a submission so the collection or form can have this.
        return self.submission
Example #2
0
    def save(self, collection=None):
        """    
        Saves the validated, cleaned form data. If a submission already exists,
        the new data will be merged over the old data.
        """

        # TODO: think about adding an "overwrite" argument to this function, default of False,
        # which will determine if an error should be thrown if the submission object already
        # exists, or if we should trust the data and overwrite the previous submission.

        # If there is no submission object, then this should just be a normal
        # Django form.  No need to call the save method, so we will raise an exception
        if not hasattr(self, "submission"):
            raise LookupError(
                "There is no submission object.  Are your creating the form with 'retrun_class=True'? If so, no need to call save."
            )

        if not self.cleaned_data:
            raise LookupError("The is_valid() method must be called before saving a form")

        # Slightly evil, do type checking to see if submission is a Submission object or string
        # If Submission object is a slug
        if isinstance(self.submission, str) or isinstance(self.submission, unicode):
            submission_slug = self.submission

            # Get or create the object
            self.submission, was_created = Submission.objects.get_or_create(slug=submission_slug, collection=collection)

        # Otherwise it should be a submission model object, if not raise
        elif not isinstance(self.submission, Submission):
            raise AttributeError("Submission %s is not a valid submission object." % self.submission)

        # We now have a submission object, so let's update the last_modified field
        self.submission.last_modified = datetime.datetime.now()
        self.submission.save()

        # Get the existing answers
        answers = Answer.objects.select_related("submission", "data_from", "field").filter(
            data_form__slug=self.slug, submission=self.submission
        )

        # Get the fields from the form post
        field_keys = []
        for key in self.fields:
            # Mangle the key into the DB form, then get the right Field
            field_keys.append(_field_for_db(key))

        # Get all fields that pertian to this dataform (from db)
        fields_from_db = self.query_data["field_query"]

        # Check for fields that aren't in the database and create a list of them
        fields_to_insert = []
        for field in fields_from_db:
            has_answer = filter(lambda a: a.field.slug == field.slug, answers)
            if has_answer:
                continue
            else:
                fields_to_insert.append(field)

        # For these new fields, create answer objects for insertion, if any
        if fields_to_insert:
            new_answers = []
            for field in fields_to_insert:
                # save the answer only if the field is in the form POST
                if field.slug in field_keys:
                    # Create a new answer object
                    answer = Answer()
                    answer.submission = self.submission
                    answer.data_form = self.query_data["dataform_query"]
                    answer.field = field
                    new_answers.append(answer)

            # Insert the new objects, if any
            if new_answers:
                insert_many(new_answers)

            # Get Answers again so that we have the pks if we had answers that were inserted
            answers = Answer.objects.select_related("submission", "data_from", "field").filter(
                data_form__slug=self.slug, submission=self.submission
            )

        # Get All possible choices from form models dict
        choices = Choice.objects.all()

        # Setup answer list so we can do a bulk update
        answer_objects = []

        # We know answers exist now, so update them if needed.
        for answer in answers:

            # Delete the choices so we can re-insert
            AnswerChoice.objects.filter(answer=answer).delete()

            answer_obj, choice_relations = self._prepare_answer(answer, choices)
            answer_objects.append(answer_obj)

            # If there are choices, do mass insert on them for each answer.
            if choice_relations:
                answer_choices = []
                for choice in choice_relations:
                    answer_choice = AnswerChoice()
                    answer_choice.answer = answer
                    answer_choice.choice = choice
                    answer_choices.append(answer_choice)

                insert_many(answer_choices)

        # Update the answers
        update_many(answer_objects, fields=["value"])

        # Return a submission so the collection or form can have this.
        return self.submission
Example #3
0
    def save(self, collection=None):
        """    
        Saves the validated, cleaned form data. If a submission already exists,
        the new data will be merged over the old data.
        """
        
        # TODO: think about adding an "overwrite" argument to this function, default of False,
        # which will determine if an error should be thrown if the submission object already
        # exists, or if we should trust the data and overwrite the previous submission.

        # If there is no submission object, then this should just be a normal
        # Django form.  No need to call the save method, so we will raise an exception
        if not hasattr(self, 'submission'):
            raise LookupError("There is no submission object.  Are your creating the form with 'retrun_class=True'? If so, no need to call save.")

        if not self.cleaned_data:
            raise LookupError("The is_valid() method must be called before saving a form")
        
        # Slightly evil, do type checking to see if submission is a Submission object or string
        # If Submission object is a slug
        if isinstance(self.submission, str) or isinstance(self.submission, unicode):
            submission_slug = self.submission
            
            # Get or create the object
            self.submission, was_created = Submission.objects.get_or_create(slug=submission_slug, collection=collection)
            
        # Otherwise it should be a submission model object, if not raise
        elif not isinstance(self.submission, Submission):
            raise AttributeError('Submission %s is not a valid submission object.' % self.submission)
        

        # We now have a submission object, so let's update the last_modified field
        self.submission.last_modified = datetime.datetime.now()
        self.submission.save()
        
        # Delete Answers if they exist and start over ;)
        Answer.objects.select_related(
            'submission',
            'data_from',
            'field').filter(
                        data_form__slug=self.slug,
                        submission=self.submission).delete()
        
        # If answers don't exist, create the records without answers so that 
        # we can populate them later and save the relationships 
        # This is more efficient then using the ORM
        #if not answers:
            
        field_keys = []
        answers = []
        for key in self.fields.keys():
            # Mangle the key into the DB form, then get the right Field
            field_keys.append(_field_for_db(key))
        
        # Get All Fields
        fields = self.query_data['fields_list']
        
        for field in fields:
            # save the answer only if the field is in the form POST
            if field['slug'] in field_keys:
                # Create a new answer object
                answer = Answer()
                answer.submission = self.submission
                answer.data_form = self.query_data['dataform_query']
                answer.field_id = field['id']
                answers.append(answer)
        
        # Update the answers
        insert_many(answers)    
        
        # Get Answers again so that we have the pks
        answers = Answer.objects.select_related('submission', 'data_from', 'field').filter(data_form__slug=self.slug, submission=self.submission)
 
            
        # Get All possible choices from form models dict
        choices = self.query_data['choice_query']
        
        # Setup answer list so we can do a bulk update
        answer_objects = []

        #Delete choice relations
        delete_many(answers, table='dataforms_answer_choice')
        
        # We know answers exist now, so update them if needed.            
        for answer in answers:
            answer_obj, choice_relations = self._prepare_answer(answer, choices)
            answer_objects.append(answer_obj)

            if choice_relations:
                for choice_relation in choice_relations:
                    answer.choice.add(choice_relation)
        
        # Update the answers
        update_many(answer_objects, fields=['value'])
            
                    
        # Return a submission so the collection or form can have this.
        return self.submission