Django遵循一对多的关系

时间:2013-10-24 17:39:10

标签: python sql django sqlite join

我在理解如何使用Django关注多层关系方面遇到了一些麻烦。显然我可以使用for循环,但我正在尝试找到一种更有效的方法(可能使用原始SQL)。该模型大致是:

Subject -> Course -> Module -> Question

它们通过外键链接(例如,Question模块的外键指向Module)。

以下作品,但速度很慢,当然不理想:

subject = "Mathematics"
courses = Subject.objects.get(name__iexact=subject).course_set.all()
avg_scores = []
for course in courses:
    modules = course.module_set.all()
    for module in modules:
        questions = module.question_set.all().filter(num_attempts__gt=20).filter(avg_score__gt=0).exclude(avg_score__isnull=True).order_by('avg_score')
        for question in questions:
            avg_scores.append(question)

我可以使用以下命令使用SQL执行此操作:

SELECT * FROM question
INNER JOIN module
ON question.module_id=module.id
INNER JOIN course
ON module.course_id=course.id
INNER JOIN subject
ON course.subject_id = subject.id
WHERE subject.name="Mathematics"
AND num_attempts > 20
AND avg_score > 0

有没有办法像:

avg_scores = Subject.objects.get(name__iexact="Mathematics").course_set.module_set.question_set.filter(num_attempts__gt=20).filter(avg_score__gt=0).exclude(avg_score__isnull=True).order_by('avg_score')

1 个答案:

答案 0 :(得分:2)

如果您的SQL查询将启动SELECT * FROM Model ...,那么您的Django查询通常应该从Model.objects.filter(...)开始。所以在这种情况下你需要像:

Question.objects.filter(module__course__subject__name = 'Mathematics',
                        num_attempts__gt = 20,
                        avg_score__gt = 0).order_by('avg_score')