Django 查询连接两个表的记录
Django query to join records of two tables
我正在使用 django-mssql 1.6.2 包和 django 1.7 从 sql 服务器 2008 获取一条或多条 tables 的记录。当我调用 "get" 或 "filter" 如下,一切都很好,但我的服务器程序很慢。考虑以下 tables:
class Contact(models.Model):
id = models.IntegerField(primary_key=True, unique=True, null=False)
address = models.CharField(max_length = 100)
phone = models.IntegerField(unique=True)
class Parent(models.Model):
id = models.IntegerField(primary_key=True, unique=True, null=False)
name = models.CharField(max_length = 50)
contact = models.OneToOneField(Contact)
class Student(models.Model):
id = models.IntegerField(primary_key=True, unique=True, null=False)
name = models.CharField(max_length = 50)
parent = models.ForeignKey(Parent)
假设我们要在模板中打印 table,例如:
Student name | Parent name | Parent phone number
John | Jack | 1111111
Susan | Jack | 1111111
Dan | Jack | 1111111
Jackie | Sara | 2222222
我使用这样的代码:
query_results = list()
parents = Parent.objects.all()
for any_parent in parents:
students = Student.objects.filter(parent=any_parent)
for student in students:
element = TempObjectForStudent()
element.student_name = student.name
element.parent_name = any_parent.name
element.parent_phone = any_parent.contact.phone
query_results.append(element)
if students.__len__() == 0:
element = TempObjectForStudent()
element.student_name = 'without any active student'
element.parent_name = any_parent.name
element.parent_phone = any_parent.contact.phone
query_results.append(element)
class TempObjectForStudent():
student_name = None
parent_name = None
parent_phone = None
使用如下模板:
{% for row in query_results %}
<tr><td>{{ row.student_name }}</td><td>{{ row.parent_name }}</td><td>{{ row.parent_phone }}</td></tr>
正如我之前提到的,问题在于此方法中 运行 大量查询的速度。我如何使用 join 在一个查询中传送所有 table 数据?
好吧,你把它搞得有点太复杂了。
不需要 TempObjectForStudent。你可以在没有它的情况下获得学生实例。只需将 related_name
添加到 Student
模型的 parent
字段,这样您就可以使用点符号简单地获取对 Parent
对象的引用。
另请注意,Django 会自动为每个模型提供 id
字段。您可以阅读更多 here and here。因此无需在您的模型中显式创建该字段。
关于你的问题,我会这样回答:
# models.py
class Parent(models.Model):
name = models.CharField(max_length = 50)
contact = models.OneToOneField(Contact)
class Student(models.Model):
name = models.CharField(max_length = 50)
parent = models.ForeignKey(Parent, related_name='students')
# views.py
parents = Parent.objects.all()
# template.html
{% for parent in parents %}
<tr>
<td>
{% with parent.students.all as students %}
{% for student in students %}
{{ student.name }}
{% empty %}
'without any active student'
{% endfor %}
{% endwith %}
</td>
<td>
{{ parent.name }}
</td>
<td>
{{ parent.contact.phone }}
</td>
</tr>
{% endfor %}
更新:
我遇到了一个 select_related
QuerySet 方法。我认为这就是您一直在寻找的!它使用 SQL JOIN
子句并在 SELECT
语句中包含所有相关对象的字段。阅读更多 here。希望对您有所帮助!
我正在使用 django-mssql 1.6.2 包和 django 1.7 从 sql 服务器 2008 获取一条或多条 tables 的记录。当我调用 "get" 或 "filter" 如下,一切都很好,但我的服务器程序很慢。考虑以下 tables:
class Contact(models.Model):
id = models.IntegerField(primary_key=True, unique=True, null=False)
address = models.CharField(max_length = 100)
phone = models.IntegerField(unique=True)
class Parent(models.Model):
id = models.IntegerField(primary_key=True, unique=True, null=False)
name = models.CharField(max_length = 50)
contact = models.OneToOneField(Contact)
class Student(models.Model):
id = models.IntegerField(primary_key=True, unique=True, null=False)
name = models.CharField(max_length = 50)
parent = models.ForeignKey(Parent)
假设我们要在模板中打印 table,例如:
Student name | Parent name | Parent phone number
John | Jack | 1111111
Susan | Jack | 1111111
Dan | Jack | 1111111
Jackie | Sara | 2222222
我使用这样的代码:
query_results = list()
parents = Parent.objects.all()
for any_parent in parents:
students = Student.objects.filter(parent=any_parent)
for student in students:
element = TempObjectForStudent()
element.student_name = student.name
element.parent_name = any_parent.name
element.parent_phone = any_parent.contact.phone
query_results.append(element)
if students.__len__() == 0:
element = TempObjectForStudent()
element.student_name = 'without any active student'
element.parent_name = any_parent.name
element.parent_phone = any_parent.contact.phone
query_results.append(element)
class TempObjectForStudent():
student_name = None
parent_name = None
parent_phone = None
使用如下模板:
{% for row in query_results %}
<tr><td>{{ row.student_name }}</td><td>{{ row.parent_name }}</td><td>{{ row.parent_phone }}</td></tr>
正如我之前提到的,问题在于此方法中 运行 大量查询的速度。我如何使用 join 在一个查询中传送所有 table 数据?
好吧,你把它搞得有点太复杂了。
不需要 TempObjectForStudent。你可以在没有它的情况下获得学生实例。只需将 related_name
添加到 Student
模型的 parent
字段,这样您就可以使用点符号简单地获取对 Parent
对象的引用。
另请注意,Django 会自动为每个模型提供 id
字段。您可以阅读更多 here and here。因此无需在您的模型中显式创建该字段。
关于你的问题,我会这样回答:
# models.py
class Parent(models.Model):
name = models.CharField(max_length = 50)
contact = models.OneToOneField(Contact)
class Student(models.Model):
name = models.CharField(max_length = 50)
parent = models.ForeignKey(Parent, related_name='students')
# views.py
parents = Parent.objects.all()
# template.html
{% for parent in parents %}
<tr>
<td>
{% with parent.students.all as students %}
{% for student in students %}
{{ student.name }}
{% empty %}
'without any active student'
{% endfor %}
{% endwith %}
</td>
<td>
{{ parent.name }}
</td>
<td>
{{ parent.contact.phone }}
</td>
</tr>
{% endfor %}
更新:
我遇到了一个 select_related
QuerySet 方法。我认为这就是您一直在寻找的!它使用 SQL JOIN
子句并在 SELECT
语句中包含所有相关对象的字段。阅读更多 here。希望对您有所帮助!