Hi
I have a set of questionnaires which has a set of questions with answers based upon choices.
I am trying to perform some calculations based on the answers the user chooses. This has evolved over time and now the calculations have changed where now the choice also has a weight assigned. So the answer could score -1 but the weight would be -10.
The function takes the choice value and multiples this by the weight.
I tried to do this in my view, but i was advised that it might be more appropriate to perform the calculation as a function within the model?
class Choice(models.Model):
question = models.ForeignKey(ProjectQuestionnaireQuestion, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
choice_value = models.CharField(max_length=20, blank=True)
choice_weight = models.IntegerField(blank=True, null=True)
def __str__(self):
return str(self.choice_text)
@property
def raw_score(self):
if not self.choice_value:
return 0
return choice_value_to_score_map.get(self.choice_value, 0)
@property
def weighted_score(self):
return self.raw_score * self.choice_weight
choice_value_to_score_map = {
'--': -2,
'-': -1,
'0': 0,
'+': 1,
'++': 2,
}
class ProjectQuestionnaireAnswer(models.Model):
YN_Choices = [
('Yes', 'Yes'),
('No', 'No'),
('Unknown', 'Unknown')
]
question = models.ForeignKey(ProjectQuestionnaireQuestion, on_delete=models.CASCADE)
answer = models.ForeignKey(Choice, on_delete=models.CASCADE,null=True)
value = models.CharField(max_length=20, blank=True)
notes = models.TextField(blank=True)
response = models.ForeignKey(ProjectQuestionnaireResponse, on_delete=models.CASCADE)
@property
def score(self):
if not self.value:
return 0 # or maybe 0, this depends on how you like to calculate
for choice in self.question.choice_set.all():
if choice.choice_value == self.value:
return choice_value_to_score_map.get(self.value, 0) * choice.choice_weight
return 0 # or maybe 0, this depends on how you like to calculate
class Meta:
constraints = [
models.UniqueConstraint(fields=['question','response'], name='project_unique_response2'),
]
def __str__(self):
return str(self.answer)
What is the benefit of doing this, does this have less of a performance impact - It doesn’t actually work at the moment, but I just trying to understand if this is the approach I should follow.
Thanks