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 (DB、疑似コード):

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 に答える