1

私は現在、友達機能 (Facebook など) を持つ Web アプリケーションを構築しています。

フレンドがフレンド申請を送信すると、 でフレンドシップ オブジェクトが作成されaccepted = Falseます。リクエストされたフレンドがリクエストを受け入れると、 にaccepted設定されます。True

これが私のモデルです(大幅に簡略化されています):

class Friendship(models.Model):
    sender = models.ForeignKey('Person', related_name='sender')
    receiver = models.ForeignKey('Person', related_name='receiver')
    accepted = models.BooleanField(default=False)

class Person(models.Model):
    person = models.OneToOneField(User)
    friends = models.ManyToManyField('self', through=Friendship)

このように持っているので、友達リクエストも管理できます。

ここで、ジョンという人物がいるとしましょう。John のすべての友達を取得したい (たとえば、John の友達リクエストを受け入れたすべての友達と、John が友達リクエストを受け入れたすべての友達)。

これが私が今やっている方法です:

def friends(person):
    friends = Friendship.objects.filter(sender=person, accepted=True) | Friendship.objects.filter(receiver=person, accepted=True)
    friends = [friendship.sender for friendship in friends if friendship.sender != person] + \
              [friendship.receiver for friendship in friends if friendship.receiver != person]
    return friends

私には、これは本当に醜く、おそらく遅くて非効率的です。Django には、このようなことを行う方法がありますか?

def friends(person):
    return person.friends.filter(accepted=True)

残念ながら、この正確なコードは機能しません。より良い方法はありますか?

4

1 に答える 1

1

最近、非常によく似たクエリを実行する必要がありました。このようなもの(または同様のもの)が機能するはずです:

def friends(person):
    friends = Person.objects.filter(Q(sender__receiver=person, sender__accepted=True) | Q(receiver__sender=person, receiver__accepted=True))
    return friends

次のように、M2M モデルの related_name 属性を使用して、関連フィールドで結合を行うことができます。Person.objects.filter(sender__accepted=True)

「友達」とは、友達関係の相手です。つまり、あなたが受信者の場合、友人は送信者であり、その逆も同様です。また、関連する名前「送信者」と「受信者」の名前を変更し、「友人」を前に追加して、上記のクエリをより明確にします。

于 2014-03-28T04:31:51.023 に答える