如何找到那些首选项是给定集合首选项列表的超集的用户?

2024-10-01 22:31:56 发布

您现在位置:Python中文网/ 问答频道 /正文

这是一个我思考了一段时间的问题,我想听听比我更有经验的Django开发人员的意见。比如说,我有以下模型:

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实现它。有什么建议或意见如何为这个问题设计模型?你知道吗


Tags: django模型truemodels选项querylistclass
1条回答
网友
1楼 · 发布于 2024-10-01 22:31:56

您可以应用第一个筛选器以仅保留集合中的首选项,然后使用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

相关问题 更多 >

    热门问题