1

这是我一直在思考的一个问题,我想听听比我更有经验的 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(数据库,伪代码):

SELECT * from UserProfile WHERE preferences is a superset of preference_list

我认为选项 2 会更有效,但我不知道如何在 Django 中实现它。任何建议或意见如何布置这个问题的模型?

4

1 回答 1

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
于 2013-04-21T17:12:24.920 回答