首页 > 解决方案 > Django Models - SQL 等效的多个表加入 DJANGO

问题描述

如何在 django (ORM) 中加入 3 个或更多表并获取结果?
已创建 3 个模型:

1.学生 2.成绩 3.详情

class Student:    
    s_id = models.IntegerField(primary_key=True)    
    s_name = models.CharField(max_length=100)  

class Marks:  
    school_id = models.IntegerField(primary_key=True)  
    s_id = models.ForeignKey(Student, on_delete=models.CASCADE)  
    score = models.IntegerField()  
    status = models.CharField(max_length=30)  

class Details:  
    address_city = models.CharField(max_length=30)  
    emailid = models.EmailField()  
    school_id = models.ForeignKey(Marks,on_delete=models.CASCADE)  
    accomplishments = models.TextField()  

我需要加入这 3 个表并获取学生姓名、分数、状态、address_city、email_id、accomplishments。
在 SQL 中,我们可以这样写:

select s_name, score, status, address_city, email_id,
accomplishments from student s inner join marks m on
s.s_id = m.s_id inner join details d on 
d.school_id = m.school_id;

请让我知道如何使用 DJANGO 代码实现相同的目标。

标签: pythondjangodjango-models

解决方案


我认为你应该保持简单而不是复杂的模型,当你有很多数据时,这不会很好。保持学生模型为主类。并将所有其他信息存储在其他表中。

class Student:    
    name = models.CharField(max_length=100)  
    marks = models.ForeignKey(Marks,on_delete=models.CASCADE)  
    school = models.ForeignKey(School,on_delete=models.CASCADE)

class Marks:    
    score = models.IntegerField()  
    status = models.CharField(max_length=30)  

class Details:  
    address_city = models.CharField(max_length=30)  
    emailid = models.EmailField()  
    accomplishments = models.TextField() 

class School:
     name = models.CharField(max_length=30)
     details = models.ForeignKey(Details)

现在执行以下查询

student = Student.objects.filter(pk=student_id).filter(school_pk=school_id)

print student.name
print student.marks.score
print student.marks.status
print student.details.address_city

对于您当前的模型,很难查询。但是您可以尝试自己编写 SQL 查询。像这样的东西

Blog.objects.extra(
    select={
        'entry_count': 'SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id'
    },
)

按照这个 https://docs.djangoproject.com/en/2.1/ref/models/querysets/#extra


推荐阅读