Уведомления

Группа в Telegram: @pythonsu

#1 Март 3, 2014 10:21:48

sedoi
Зарегистрирован: 2013-09-20
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Выборка из двух таблиц

Здравствуйте!
Имеется база студентов и их оценки по разным предметам, нужно вывести список студентов отсортированный по возрастанию средней оценки:

class Student(models.Model):
    class Meta():
        db_table="student"
    student_name = models.CharField(max_length = 30)
class Rating(models.Model):
    class Meta():
        db_table="rating"
    rating_lesson = models.IntegerField()
    rating_student = models.ForeignKey(Student)

Код на SQL выглядел бы так:
SELECT student_name, (AVG(rating_lesson)) AS rating FROM student
INNER JOIN rating ON rating.rating_student_id=student.id
GROUP BY student.id
ORDER BY rating DESC

Пробовал так:
return render_to_response('site.html', {'student' : Student.objects.all().filter(rating__rating_student_id=Student.objects.all()).annotate(total=Count('id')).order_by('-rating__rating_lesson')})

Но тогда не выводится средняя оценка и не знаю как её вывести на экран в site.html:
{% for name in student %}
        <tr>
          <td>{{ name.student_name }}</td>
          <td>тут должна быть средняя оценка</td>
      </tr>
{% endfor %}

Отредактировано sedoi (Март 3, 2014 21:59:24)

Офлайн

#2 Март 3, 2014 19:09:53

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

Выборка из двух таблиц

{% for name in student %}
        <tr>
          <td>{{ name.student_name }}</td>
          <td>{{ name.rating_set.rating_lesson }}</td>
      </tr>
{% endfor %}
если несколько оценок, то
{% for name in student %}
        <tr>
          <td>{{ name.student_name }}</td>
          <td>{% for ratings in name.rating_set.all %}
                     {{ ratings.rating_lesson }}
                 {% endfor %}
         </td>
      </tr>
{% endfor %}



————————————————
-*- Simple is better than complex -*-

Отредактировано terabayt (Март 3, 2014 19:12:47)

Офлайн

#3 Март 3, 2014 21:35:00

sedoi
Зарегистрирован: 2013-09-20
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Выборка из двух таблиц

terabayt
Да, спасибо, а как можно получить среднюю оценку?
У меня сейчас примерно выводит так:
Фамилия_первая 4 5 3 3
Фамилия_вторая 4 3 2
Фамилия_третья 2 4 5 2

А необходимо узнать среднюю оценку каждого студента и вывести в список по возрастанию. Для примера выше было бы так:
Фамилия_первая 3.75
Фамилия_третья 3,25
Фамилия_вторая 3

Update:
Решил, всё таки, сделать запрос чистым SQL:
from django.db import connection, transaction
    cursor = connection.cursor()
    cursor.execute('''SELECT student_name, ROUND(AVG(rating_lesson), 2) AS avg_rating FROM student
                    INNER JOIN rating ON rating.rating_student_id=student.id
                    GROUP BY student.id
                    ORDER BY avg_rating DESC''')
    out = []
    while(True):
        row = cursor.fetchone()
        if(row == None):
            break
        else:
            out.append(row)
    return render_to_response('site.html', {'student' : out})

Если кто скажет как сделать такое в ORM, то буду благодарен

Отредактировано sedoi (Март 3, 2014 22:33:56)

Офлайн

#4 Март 4, 2014 00:42:18

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

Выборка из двух таблиц

Чистый sql это всегда красиво!
А для большей красоты

while True:
        row = cursor.fetchone()
        if not row:
            break
        out.append(row)
или же так
out = [i for i in cursor.fetchone()]



————————————————
-*- Simple is better than complex -*-

Отредактировано terabayt (Март 4, 2014 00:49:02)

Офлайн

#5 Март 4, 2014 11:50:41

ilnur
От: Казань
Зарегистрирован: 2009-01-06
Сообщения: 524
Репутация: +  22  -
Профиль   Отправить e-mail  

Выборка из двух таблиц

Student

sedoi
А необходимо узнать среднюю оценку каждого студента и вывести в список по возрастанию. Для примера выше было бы так:
вроде так

Student.objects.values('student_name').aggregate(avg=Avg('rating__rating_lesson')).ordr_by('avg')

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version