假設我有以下型號:添加額外的多對多領域Django的查詢集
class Thing(models.Model):
name = models.CharField(max_length=100)
ratings = models.ManyToManyField('auth.User', through='Rating')
class Rating(models.Model):
user = models.ForeignKey('auth.User')
thing = models.ForeignKey('Thing')
rating = models.IntegerField()
所以我有很多事情,每個用戶可以給每一個事情。我也有一個視圖,顯示所有事物的列表(並且它們數量巨大),用戶分配給他們每個人的評分。我需要一種方法來檢索數據庫中的所有數據:帶有額外字段user_rating
的事物最多取自一個(因爲我們有固定用戶)相關評級對象。
平凡解看起來像這樣:
things = Thing.objects.all()
for thing in things:
try:
thing.user_rating = thing.ratings.objects.get(user=request.user).rating
except Rating.DoesNotExist:
thing.user_rating = None
但是,這種方法的缺陷是顯而易見的:如果我們有500分的事情,我們會做501個請求數據庫。每頁。每個用戶。這是該網站瀏覽次數最多的頁面。這個任務很容易用SQL JOIN解決,但實際上我有更復雜的模式,我肯定會受益於Django模型框架。所以問題是:是否可以這樣做Django方式?如果不是,考慮到這些任務非常普遍,這將是非常奇怪的。
據我所知,annotate()
或select_related()
都不會幫助我。
您仍然得到每個用戶的查詢,而不是聚合。 – Tom 2012-01-06 17:33:58
好的,但它絕對不是完美的。如果事情分成頁面怎麼辦?比如說,有10000個東西,頁面包含100個條目。第二個循環將不得不查看所有可能的10000個評分。 – user285176 2012-01-06 19:03:10
@Tom至少有2個查詢,而不是n + 1 – user285176 2012-01-06 19:05:18