def save(self, *args, **kwargs): if self.answer_type not in [ MultiChoiceAnswer.choice_name(), MultiSelectAnswer.choice_name()]: self.options.all().delete() invalidate_obj(self.qset) # to fix update of flow_question update return super(Question, self).save(*args, **kwargs)
def save(self, *args, **kwargs): if self.answer_type not in [ MultiChoiceAnswer.choice_name(), MultiSelectAnswer.choice_name() ]: self.options.all().delete() return super(Question, self).save(*args, **kwargs)
def params_display(self): params = [] for arg in self.text_arguments: if self.question.answer_type == MultiChoiceAnswer.choice_name(): params.append(self.question.options.get(order=arg.param).text) else: params.append(arg.param) return params
def display_text(self, channel=None): text = self.text if channel and channel== USSDAccess.choice_name() and self.answer_type == MultiChoiceAnswer.choice_name(): extras = [] #append question options for option in self.options.all().order_by('order'): extras.append(option.to_text) text = '%s\n%s' % (text, '\n'.join(extras)) return text
def display_text(self, channel=USSDAccess.choice_name(), context={}): text = self.text if channel == USSDAccess.choice_name() and self.answer_type == MultiChoiceAnswer.choice_name(): extras = [] # append question options for option in self.options.all().order_by('order'): extras.append(option.to_text) text = '%s\n%s' % (text, '\n'.join(extras)) return Template(text).render(Context(context))
def update_parameter_list(cls, batch): """Updates the parameter list for this batch. Basically checks all the target_groups registered in this batch and ensures required parameter list is updated. Presently because the entire group parameters required in a batch would typically be less than 10, The strategy employed here shall be to delete all parameters and create new when called. Questions in returned question set does not necessarily belong to any flow. :param batch: :return: """ param_list, _ = cls.objects.get_or_create(batch=batch) param_list.questions.all().delete() # now create a new target_groups = RespondentGroup.objects.filter( questions__qset__id=batch.id) question_ids = [] # loop through target_groups to get required template parameters for group in target_groups: map( lambda condition: question_ids.append(condition.test_question. id), group.group_conditions.all()) parameters = ParameterTemplate.objects.filter( id__in=question_ids).order_by('identifier') prev_question = None for param in parameters: # going this route because param questions typically would be small question = ParameterQuestion( **{ 'identifier': param.identifier, 'text': param.text, 'answer_type': param.answer_type, 'qset': param_list }) question.save() if prev_question: QuestionFlow.objects.create(question=prev_question, next_question=question) prev_question = question if question.answer_type in [ MultiChoiceAnswer.choice_name(), MultiChoiceAnswer ]: for option in param.options.all(): QuestionOption.objects.create(order=option.order, text=option.text, question=question) return param_list
def generate_random_samples(cls, from_survey, to_survey, ea): """ Used to generate random samples from listing conducted by from_survey to be used by to_survey to do: optimize this method queries :param from_survey: Survey from which listing was done :param to_survey: Survey for whom the random sample is being generated. :param ea: the EA where the survey was conducted :return: None """ if cls.samples(to_survey, ea).exists(): raise cls.SamplesAlreadyGenerated('Samples already generated') if to_survey.has_sampling is False or from_survey.has_sampling is False: raise ValueError('Either source or destination survey does not support sampling') valid_interviews = from_survey.interviews.filter(ea=ea, # the listed interviews in the ea question_set=from_survey.listing_form).values_list('id', flat=True) #valid_interviews = set(valid_interviews) # now get the interviews that meet the randomization criteria for criterion in to_survey.randomization_criteria.all( ): # need to optimize this answer_type = criterion.listing_question.answer_type if answer_type == MultiChoiceAnswer.choice_name(): value_key = 'value__text' else: value_key = 'value' answer_class = Answer.get_class(answer_type) kwargs = { 'question': criterion.listing_question, 'interview__id__in': valid_interviews, } # if qs: # kwargs['interview__id__in'] = valid_interviews valid_interviews = criterion.qs_passes_test(value_key, answer_class.objects.filter( **kwargs). only('interview__id').values_list('interview__id', flat=True)) valid_interviews = list(valid_interviews) random.shuffle(valid_interviews) random_samples = valid_interviews[:to_survey.sample_size] samples = [] for interview_id in random_samples: samples.append( ListingSample( survey=to_survey, interview_id=interview_id)) with transaction.atomic(): ListingSample.objects.bulk_create(samples)
def update_parameter_list(cls, batch): """Updates the parameter list for this batch. Basically checks all the target_groups registered in this batch and ensures required parameter list is updated. Presently because the entire group parameters required in a batch would typically be less than 10, The strategy employed here shall be to delete all parameters and create new when called. Questions in returned question set does not necessarily belong to any flow. :param batch: :return: """ param_list, _ = cls.objects.get_or_create(batch=batch) param_list.questions.all().delete() # now create a new target_groups = RespondentGroup.objects.filter( questions__qset__id=batch.id) question_ids = [] # loop through target_groups to get required template parameters for group in target_groups: map(lambda condition: question_ids.append( condition.test_question.id), group.group_conditions.all()) parameters = ParameterTemplate.objects.filter( id__in=question_ids).order_by('identifier') prev_question = None for param in parameters: # going this route because param questions typically would be small question = ParameterQuestion(**{'identifier': param.identifier, 'text': param.text, 'answer_type': param.answer_type, 'qset': param_list}) question.save() if prev_question: QuestionFlow.objects.create( question=prev_question, next_question=question) prev_question = question if question.answer_type in [ MultiChoiceAnswer.choice_name(), MultiChoiceAnswer]: for option in param.options.all(): QuestionOption.objects.create( order=option.order, text=option.text, question=question) return param_list
def _get_possible_samples(): if to_survey.has_sampling is False or from_survey.has_sampling is False: raise ValueError( 'Either source or destination survey does not support sampling' ) valid_interviews = from_survey.interviews.filter( ea=ea, # the listed interviews in the ea question_set=from_survey.listing_form).values_list('id', flat=True) #valid_interviews = set(valid_interviews) # now get the interviews that meet the randomization criteria for criterion in to_survey.randomization_criteria.all( ): # need to optimize this answer_type = criterion.listing_question.answer_type if answer_type == MultiChoiceAnswer.choice_name(): value_key = 'value__text' else: value_key = 'value' answer_class = Answer.get_class(answer_type) kwargs = { 'question': criterion.listing_question, 'interview__id__in': valid_interviews, } # if qs: # kwargs['interview__id__in'] = valid_interviews valid_interviews = criterion.qs_passes_test( value_key, answer_class.objects.filter( **kwargs).only('interview__id').values_list( 'interview__id', flat=True)) valid_interviews = list(valid_interviews) random.shuffle(valid_interviews) random_samples = valid_interviews[:to_survey.sample_size] samples = [] for interview_id in random_samples: samples.append( ListingSample(survey=to_survey, interview_id=interview_id)) return samples
def save(self, *args, **kwargs): if self.answer_type not in [MultiChoiceAnswer.choice_name(), MultiSelectAnswer.choice_name()]: self.options.all().delete() return super(Question, self).save(*args, **kwargs)