django order_with_respect_to包含相关对象

时间:2012-01-03 16:20:35

标签: django

我正在开发一个包含大量相关对象的django应用程序。我有测试对象,每个测试对象都有一组有序的问题(每个问题都有一个correct_answer属性)。我还有测试尝试对象,它们通过外键与测试对象相关,并且每个对象都有一组有序的问题尝试,每个问题都有一个选择属性。从本质上讲,每个问题尝试都对应一个问题(测试尝试只通过验证它与问题相关的问题尝试次数与问题相同)然后我可以通过输出values_list来检查百分比的正确与错误of correct_answers和选择并比较两个列表。我的模型看起来像这样:

ANSWERS = ((0,''),(1,'A'),(2,'B'),(3,'C'),(4,'D'),(5,'E'))

class Question(models.Model):
    test = models.ForeignKey(Test,related_name='questions')
    correct_answer = models.IntegerField(max_length=1,choices=ANSWERS)

    def _get_score(self):
        answers = self.test.test_attempts.values_list('answers_choice',flat=True)[self.test.get_question_order().index(self.pk)::self.test.questions.count()]
        scores = [x==self.correct_answer for x in answers]
        length = len(correct)
        if length == 0:
            return 0
        return float(sum(scores))/length
    score = property(_get_score)

    class Meta:
        order_with_respect_to = 'test'

class Test(models.Model):
    testID = models.CharField(max_length=50,verbose_name='Test identification information')

    def _get_score(self):
        scores = [x.score for x in self.test_attempts.all()]
        length = len(scores)
        if length == 0:
            return 0
        return float(sum(scores))/length

    score = property(_get_score)

class QuestionAttempt(models.Model):
    test_attempt = models.ForeignKey(TestAttempt,related_name='answers')
    choice = models.IntegerField(max_length=1,choices=ANSWERS)

    def isCorrect(self):
        return self.choice == Question.objects.get(pk=self.test_attempt.test.get_question_order()[self.test_attempt.get_questionattempt_order().index(self.pk)]).correct_answer

    class Meta:
        order_with_respect_to = 'test_attempt'

class TestAttempt(models.Model):
    test = models.ForeignKey(Test,related_name='test_attempts')
    student = models.ForeignKey(UserProfile,related_name='test_attempts')

    def _get_score(self):
        responses = self.answers.values_list('choice',flat=True)
        correctAnswers = self.test.questions.values_list('correct_answer',flat=True)
        s = [x==y for x,y in zip(responses,correctAnswers)]
        length = len(s)
        if length == 0:
            return 0
        return float(sum(s))/length

    score = property(_get_score)

    class Meta:
        unique_together = ('student','test')

如果你看一下QuestionAttempt模型,在那个isCorrect方法中,你会看到我的困境。似乎这是检查获取每个问题粒度以检查给定问题尝试是对还是错的唯一方法。我的问题是,这一个语句实际上是3或4个唯一的数据库查询(我甚至不能告诉它有这么多)。我正在考虑使用F语句,但我不知道django在指定order_with_respect_to时使用的排序列的默认名称。另外,要获得给定问题的分数,我还需要进行3 + db查询。有一个更好的方法吗?如何访问订单的db条目。我做了一些搜索,并将一个名为_order的属性应用于问题和问题尝试模型。我可以可靠地使用它吗?这将极大地简化一些代码,因为我可以使用_order属性上的过滤器来查询数据库

1 个答案:

答案 0 :(得分:1)

问题在于您在设置模型时的逻辑。 QuestionAttempt应与Question直接相关。依赖于排序是相同的,充其量是可疑的,并且很可能在某些时候失败。