The function to calculate the score is always returning zero regardless of the values.
@property
def score(self):
if not self.value:
return 0
for choice in self.question.choice_set.all():
if choice.choice_value == self.value:
return choice_value_to_score_map.get(self.value) * choice.choice_weight
return 0
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
for choice in self.question.choice_set.all():
if choice.choice_value == self.value:
return choice_value_to_score_map.get(self.value) * choice.choice_weight
return 0
class Meta:
constraints = [
models.UniqueConstraint(fields=['question','response'], name='project_unique_response2'),
]
def __str__(self):
return str(self.answer)
If I print out the value of answer.score it always returns 0 when using:
all_q_answered = ProjectQuestionnaireAnswer.objects.filter(response = q_response, answer__isnull=False).values('question__choice__choice_weight')
total_score = 0
for answer in q_answered:
total_score = total_score + answer.score
Hey there!
There’s a few question that you need to ask yourself to respond to this.
First, is self.value a value that will evaluate to True?
Second are there any choices into self.question.choice_set.all() you can check using .count()
Third, are choice.choice_value the exact same of self.value?
You can check this by running on debug mode on PyCharm/Vscode, or doing on the oldschool way: print your way through the console.
I’ve corrected the function. but this if choice.choice_text == self.answer never seems to evaluate to true even when the two matches and I’m not sure why.
I printed out both values and they are == but the function never moves onto the if true section.
for choice in self.question.choice_set.all():
if choice.choice_text == self.answer:
print("This One Matches")
return choice_value_to_score_map.get(self.answer,0) * choice.choice_weight
That’s what I did Ken. Not all match but some do, but still the print('This One Matches') never fires. Ill keep trying but I suspect it’s something to do with self.question.choice_set.all():?
Sorry, i meant this is what I tried before posting.
No evidence of prior failed or failing project
No evidence of prior failed or failing project
No match
for choice in self.question.choice_set.all():
print(choice.choice_text)
print(self.answer)
if choice.choice_text == self.answer:
print("This One Matches")
return choice_value_to_score_map.get(self.answer,0) * choice.choice_weight
else:
print('No match')
So the first two matches, but still throws No Match ?
Next step is to check the data type for these to ensure you’re testing apples to apples.
e.g. print(type(choice.choice_text)), print(type(self.answer))
self.answer is returning the <class 'app.models.Choice'> which is from:
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.answer:
return 0 # or maybe 0, this depends on how you like to calculate
for choice in self.question.choice_set.all():
print(type(choice.choice_text))
print(type(self.answer))
if choice.choice_text == self.answer:
print("This One Matches")
return choice_value_to_score_map.get(self.answer,0) * choice.choice_weight
else:
print('No match')
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)
Yes, absolutely. But this has nothing to do with anything we’re currently discussing.
The original issue is that you’re not performing a proper comparison. You’re trying to compare a string to an instance of a Model.
But as I see it, this is an X-Y Problem. You’re manually searching through a queryset rather than constructing a query to directly retrieve the desired value. If you write the right query, it eliminates the need for the manual search.