2013-04-21 13 views
1

這是一個我一直在思考的問題,我想聽聽更多有經驗的Django開發人員的意見。說,我有以下型號:如何找到那些偏好是給定集合preference_list超集的用戶?

class Preference(models.Model): 
    name = models.CharField(max_length=50, unique=True) 

class UserProfile(AbstractUser): 
    preferences = models.ManyToManyField(Preference, blank=True) 

例如,偏好可能與食物有關。我喜歡牛肉和土豆,所以他們會成爲我的偏好。

例如,找到至少有牛肉和土豆的用戶的最有效方法是什麼?所以,我想找一個用戶,除了牛肉和土豆之外,還可以在他們的喜好中加入冰淇淋和沙拉。

選項1(迭代):

query = UserProfile.objects.all() # all user objects 

for p in preference_list:   # preference_list contains beef and potatoes 
    query = query.filter(preferences__in==p.id) 

選項2(DB,僞代碼):

SELECT * from UserProfile WHERE preferences is a superset of preference_list 

我覺得選項2會更有效率,但我不知道如何來實現它在Django。任何建議或意見如何爲這個問題制定模型?

回答

0

您可以將第一過濾器,以保持在僅設置首選項,那麼請確保您有使用Count集合中的所有喜好:

preferences = ('beef', 'potatoes') 
UserProfile.objects.filter(preferences__name__in=preferences 
    ).annotate(pref_count=models.Count('preferences') 
    ).filter(pref_count=len(preferences) 

這確實可能更有效,因爲它不會增加一個加入搜索每個偏好(僞代碼):

SELECT * FROM userprofile 
    LEFT OUTER JOIN userprofile_preferences 
    LEFT OUTER JOIN preference 
    WHERE preference IN (beef, potato) 
    GROUP BY userprofile 
    HAVING COUNT(userprofile_preferences) = 2 
+0

感謝您的回覆,您的解決方案似乎也在實踐中工作。 是否可以創建一個包含Preference對象的容器類PreferenceSet,然後比較用戶的PreferenceSet對象? Django中是否有某種超集或子集方法可以在這些PreferenceSet對象之間進行比較? – user2304261 2013-04-21 20:03:45

相關問題