1

我正在使用 django-mssql 1.6.2 包和 django 1.7 从 sql server 2008 获取一个或多个表记录。当我如下调用“get”或“filter”时,一切都很好,但我的服务器程序很慢。考虑下表:

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)

假设我们要在模板中打印一个表格,例如:

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 在一个查询中传递所有表数据?

4

1 回答 1

1

好吧,你让它有点太复杂了。

不需要 TempObjectForStudent。您可以在没有它的情况下获取学生实例。只需在模型的字段中添加一个,这样related_name您就可以简单地使用点符号来引用对象。StudentparentParent

另请注意,Django 会id自动为每个模型提供字段。你可以在这里这里阅读更多。因此,无需在模型中显式创建该字段。

关于你的问题,我会这样做:

# 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_relatedQuerySet 方法。我想这就是你一直在寻找的!它使用 SQL子句并在语句JOIN中包含所有相关对象的字段。在这里SELECT阅读更多。我希望它有帮助!

于 2016-07-30T22:33:47.890 回答