2016-02-22 2 views
1

Я перемещаю код с Django 1.6 до 1.9. В 1.6 я имел этот кодquery.group_by in Django 1.9

models.py

class MyReport(models.Model): 
    group_id = models.PositiveIntegerField(blank=False, null=False) 

views.py

query = MyReport.objects.filter(owner=request.user).query 
query.group_by = ['group_id'] 
entries = QuerySet(query=query, model=MyReport) 

Запрос будет возвращать один объект для каждого 'group_id'; из-за того, как я его использую, любая строка таблицы с group_id будет выполнять роль представителя.

С 1.9 этот код не работает. Запрос после того, как во второй строке выше:

SELECT "reports_myreport"."group_id", ... etc FROM "reports_myreport" WHERE "reports_myreport"."owner_id" = 1 GROUP BY "reports_myreport"."group_id", "reports_report"."otherfield", ... 

В основном это список всех полой таблицы в группе по статье, делая запрос возвращал всю таблицу.

Ever, хотя в отладчике я вижу

query.group_by = ['group_by'] 

Он не похож на query.group_by является методом в версии 1.9 и не делает переключающий журналы 1,7-1,9 предполагает, что что-то изменилось.

Есть ли лучший способ - не в зависимости от внутренних вещей Django - я могу использовать для моего запроса?

Любой способ исправить мой текущий запрос?

+0

Что такое 'group_id' в отношении вашего' MyReport'? Не могли бы вы показать соответствующие части своих моделей? – Sayse

+0

@Sayse 'group_id '- это простое поле в режиме. Я отредактировал вопрос в соответствующих строках – mibm

+0

А я, конечно, ожидал, что это внешний ключ ... вы ищете 'MyReport.objects.filter (owner = request.user) .distinct ('group_id')'? – Sayse

ответ

0

Вы можете использовать order_by(), чтобы получить заказ по результатам, в том же запросе вы можете заказать по второму критерию.

Если вы хотите получить группы, вам потребуется перебрать коллекцию, чтобы получить эти значения.

Если вы потребляете все результаты, возвращаемые запросом, вы можете рассмотреть следующие вопросы:

а) itertools.groupby, что делает в оперативной памяти группу, вместо этого, но вы не должны использовать его для больших наборов данных.

б) Другой вариант заключается в использовании Manager.raw() но вам нужно будет написать SQL в Django, как это:

for report in MyReport.objects.raw('SELECT * FROM reporting_report GROUP by group_id'): 
    print(report) 

Это будет работать для больших наборов данных, но вы можете потерять совместимость с некоторым СУБД.

Бонус: Я рекомендую вам понять, что именно сделал старый код перед выполнением перезаписи.

+0

Старый код вернет одну запись (полная строка таблицы) для каждого group_id. Работало ли оно по ошибке, и теперь работает так, как было разработано, я не знаю. Оба решения должны работать, но они страдают от проблем, как вы сами упоминали. Мое решение (не может заставить 'code' работать) в комментарии выше также работает, но я делаю запросы как число групп, которые далеки от идеального ... – mibm

+1

По-видимому, старый код работал по ошибке. Выполнение group_by без какой-либо совокупности на самом деле не определено. Предложения выше (и мои собственные в предыдущем комментарии) работают. В Postgres это можно сделать проще. – mibm

Смежные вопросы