【问题标题】:How to retrieve all the data from 3 different tables in one query?如何在一个查询中从 3 个不同的表中检索所有数据?
【发布时间】:2019-09-29 14:28:36
【问题描述】:

我想做以下事情,但我不明白该怎么做:

为每个班级显示该班级的所有学生,为该班级的每个学生显示该学生的所有统计数据。

我的模型是:

class Classes(models.Model):
    name = models.CharField(max_length=256)
    day_and_time= models.CharField(max_length=256)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse("classesapp:class_detail", kwargs={"pk": self.pk})


class Students(models.Model):
    name = models.CharField(max_length=256)
    student_class =  models.ForeignKey(
        Classes, related_name = 'students', on_delete=models.SET_NULL, null=True
    )

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse("classesapp:student_detail", kwargs={"pk": self.pk})

class Statistics(models.Model):
    student= models.ForeignKey(
        Students, related_name='statistics', on_delete=models.CASCADE, null=True
    )
    date = models.DateField(blank=True, null=True)
    dictation_score = models.FloatField()
    writing_score = models.FloatField()
    test_score = models.FloatField()
    grammar_score = models.FloatField()
    in_class_performance = models.FloatField()

    class Meta:
        ordering = ["-date"]

    def get_absolute_url(self):
        return reverse("classesapp:classes_list")

我的 ClassesDetailView 是:

class ClassesDetailView(DetailView):
    queryset  = models.Classes.objects.select_related('statistics')
    context_object_name = "class_detail"
    model = models.Classes
    template_name = "classesapp/class_detail.html"

我知道我必须覆盖查询集,我尝试了 select_relatad 但仍然找不到解决方案。 提前谢谢!

【问题讨论】:

    标签: python django django-models django-queryset


    【解决方案1】:

    它将运行 2 个循环。根据您的模型,class 可以有很多 studentsstudent 可以有很多 statistics
    更新:

    result = []  
    
    for student in Students.objects.all(): 
    
        student_data = {}
        student_data['student_name'] = student.name
        student_data['class_name'] = student.student_class.name
        statistics_data = []  
    
        for statistics in student.statistics.all():  
    
            statistics_data.append({
            'dictation_score': statistics.dictation_score,
            'writing_score': statistics.writing_score,
            'grammer_score': statistics.grammer_score,
            'in_class_performance': statistics.in_class_performance
            })  
    
        student_data['statistics_data'] = statistics_data  
    
    result.append(student_data)
    

    【讨论】:

    • 您好,谢谢您的回答。我在shell中尝试过,但它不起作用。我得到的错误是select_related('statistics)Invalid field name(s) given in select_related: 'statistics'. Choices are: student_class。我试图修复它,但仍然无法正常工作。但是,您提供的这个答案是否可以在 ClassDetailView 中使用?我认为它会引发 404 错误,找不到类详细信息,因为当我在此处询问之前尝试不同的查询时,总是会出现此错误。再次感谢您的回答。
    • @ptifti remove selected_related
    • @ptifti 我更新了我的答案。如果是对的,请接受答案并点赞
    • 您可以使用 select_related()prefetch_related() 优化 SQL 方面
    • @NaveenJain 再次感谢您的回答。您提供的代码正在运行,但这不是我想要的,如果我使用 ```for student in students: blablabla for stat instudents.statistics.all() 创建 StudentsDetailView,它似乎就像学生的默认查询集。再次感谢您的回答!
    最近更新 更多