問題描述:
使用Django的ORM建立了如下Model:
class Book(models.Model):
name = models.CharField(max_length=300)
pages = models.IntegerField()
price = models.DecimalField(max_digits=10, decimal_places=2)
authors = models.CharField(max_length=300)
publisher = models.CharField(max_length300)
pub_date = models.DateField()
現(xiàn)在想查詢以字段authors分組,查出每個作者所著所有書的總頁書,用SQL語句可以很容易的完成此任務(wù):
SELECT *, SUM(pages) AS total_pages
FROM Book
GROUP BY authors;
那么如何用Django自帶的ORM接口實現(xiàn)呢?
方法如下:
from django.db.models import Sum
result = Book.objects.values("authors").annotate(total_pages=Sum("pages")).all()
注意事項:
如果你在定義Book模型時指定的默認的排序字段,如下:
class Book(models.Model):
...同上...
class Meta:
ordering = ["name"]
那么,上述result的查詢語句會得到錯誤的結(jié)果, 其所執(zhí)行的SQL語句如下
SELECT *, SUM(pages) AS total_pages
FROM Book
GROUP BY authors, name
ORDER BY name;
也就是說默認的排序字段(在這里是name)也會自動加入到GROUP BY子句中. 要避免這樣的情況,只需在查詢時清空默認的order by排序條件即可:
from django.db.models import Sum
result = Book.objects.values("authors").annotate(total_pages=Sum("pages")).order_by()
ps:你可以通過以下方法查看查詢集的對應(yīng)SQL語句
raw_sql = result.query
print(raw_sql)
或者安裝django-extensions插件,然后使用python manage.py shell_plus --print-sql
命令進入Shell,在此Shell中你通過Django對數(shù)據(jù)庫執(zhí)行的所有操作都會自動打印出其對應(yīng)的SQL語句.
除了上述方法贸伐,還有另外一種:
book_list = Book.objects.all()
book_list.query.group_by = ['authors']
這種方法是通過直接操作query對象的屬性膛腐,更容易些,然而我不太懂Query對象姨伤,所以不太敢用动看。