Django-запрос на объединение записей двух таблиц

Я использую пакет 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>

Как я упоминал ранее, проблема заключается в скорости выполнения большого количества запросов в этом методе. Как я могу использовать объединение, чтобы доставить все данные таблицы в одном запросе?

1 ответ

Решение

Хорошо, ты сделал это слишком сложным.

Нет необходимости в TempObjectForStudent. Вы можете получить экземпляр студента без этого. Просто добавьте related_name тебе Student модели parent поле, так что вы можете получить ссылку на Parent объект просто с помощью точечной нотации.

Также обратите внимание, что 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_related Метод QuerySet. Я думаю, что это то, что вы искали! Он использует SQL JOIN и включает в себя все поля связанного объекта в SELECT заявление. Узнайте больше здесь. Я надеюсь, что это помогает!

Другие вопросы по тегам