Django getting only the most recent object after filtering
I am working on a questionnaire type app for Django. When participants complete a questionnaire an AnswerSet object is created which links their user object to a list of QuestionAnswer object, one for each question that they answer.
class AnswerSet(models.Model): user=models.ForeignKey(User) questionnaire=models.ForeignKey(Questionnaire) class QuestionAnswer(models.Model): question = models.ForeignKey(Question) answer = models.CharField(max_length=255) answer_set = models.ForeignKey(AnswerSet)
The app allows people to re-answer a questionnaire, and in this case renders the form using their existing answers, and for answers that are updated, a new QuestionAnswer object is created and saved.
My question therefore is this:
In order to display the most recent answer when the participant is editing the questionnaire, I want to be able to get an AnswerSet, and then filter the QuestionAnswers so that I get a QuestionAnswer for each question, and where there are more than one QuestionAnswer for any question, I only want to see the most recent one
Thanks to the suggestion by @Rohan and this post Django query select distinct by field pairs I have found a solution that works for me, hopefully someone else will find it useful too! I have added a new model:
class LatestQuestionAnswer(models.Model): question = models.ForeignKey(Question) question_answer = models.ForeignKey(QuestionAnswer) answer_set = models.ForeignKey(AnswerSet) created = created = models.DateTimeField(auto_now_add=True)
And overridden the save function on my QuestionAnswerModel so it looks like:
def save(self, force_insert=False, force_update=False, using=None): super(QuestionAnswer, self).save(force_insert=force_insert, force_update=force_update, using=using) try: record = LatestQuestionAnswer.objects.get(question=self.question, answer_set=self.answer_set) if record.question_answer == self: return#nothing to do no point updating the record as it is already correct except ObjectDoesNotExist: record = LatestQuestionAnswer(question=self.question, answer_set= self.answer_set) record.question_answer = self record.save()
Now whenever I need to get a list of all the most recent QuestionAnswers I can do something like this:
most_recent_answers = [record.question_answer for record in LatestQuestionAnswer.objects.filter(answer_set=<an_answer_set>)]