0

私は、PrivateMessages のリストを返さない理由を理解しようとして、この問題に取り組んできました。別の目ですぐに見つけられることもあるので、誰かがエラーを見つけてくれることを願ってここに投稿します。

これは、20 個以下のプライベート メッセージを取得し、同じユーザーの重複メッセージを削除する機能です。つまり、返された pm のバッチには、ユーザーごとに 1 つのメッセージのみが送信されます。

また、サイレント リストにあるユーザーも除外されます。これらは正常に機能しているので、サイレンシング ビットとは関係ないと思います。

remove_duplicate_users を呼び出した後、次のクエリで使用する最後のオブジェクトの ID を取得します。

リスト内の 20 個のオブジェクトを返す準備ができるか、クエリが何も返さないまで、すすぎを繰り返します。

def get_private_messages(request):
    ss = Silenced.objects.filter(user=request.user)
    last_pm_id = None
    n = 20
    bl = []
    while True:
        if last_pm_id:
            pmr = PrivateMessage.objects.filter(user=request.user,hidden=False,id__lt=last_pm_id).exclude(sender__in=[s.brat for s in ss]).order_by('-id')[:n]
        else:   
            pmr = PrivateMessage.objects.filter(user=request.user,hidden=False).exclude(sender__in=[s.brat for s in ss]).order_by('-id')[:n]
        l = list(pmr)
        bl = bl + l
        bl = remove_duplicate_senders(bl)
        n = 20 - len(bl)
        last_pm_id = bl[-1].id
        if len(bl) >= 20 or not pmr:
            break

    return HttpResponse(bl)

これは、重複したユーザー メッセージを削除する機能です。pin または note という名前のユーザーを例外とし、pm.info1 がwelcome に一致する場合は、最初の午後 10 時のみが持っています。

def remove_duplicate_senders(pmr):
    l = []
    a = False
    for p in pmr:
        a = True
        if p.sender.username in ['pin','note'] or p.info1=='welcome':
            l.append(p)
            continue
        for px in l:
            if p.sender.username == px.sender.username:
                a = False
                break
        if a:
            l.append(p)
    return l

私がテストしているユーザーは午後 60 時を超えていますが、最初の午後 20 時を取得しようとすると無限ループのように見えます。他のユーザーでも機能しますが、最初のユーザーで午後が順序付けられる方法に何かがあり、エラーが発生しています。

これについての洞察は大歓迎です、ありがとう。

4

2 に答える 2

0

同一ユーザーのPMが連続しすぎて、n個のプライベートメッセージを取得しようとしても20個に達しないことが判明しました。全ユーザーのリストを作成する機能を追加しましたbl を削除し、クエリでそれらを除外しました。返信ありがとうございます。

于 2012-10-05T03:29:39.950 に答える
0

あなたのブレーク条件は無効だと思います:

if len(bl) >= 20 or not pmr:
    # Stop if I have more than 20 messages? Shouldn't I continue filtering?
    break

次のようにする必要があります。

if n >= 0:
    # Stop only if I have 20 or less [n = 20 - len(bl)], continue otherwise
    break

私は何かを誤解しているかもしれませんが、while ループの最後の部分は副作用のある部分です。また、読みやすいようにコードを書き直すことを検討してください。

于 2012-10-04T22:25:50.140 に答える