1

私は以下のようないくつかのクエリで発生します:

bphoto = B_Photo.objects.filter(q_user).order_by('-pub_date')
bactivity = B_Activity.objects.filter(q_user).order_by('-pub_date')
bpart = B_Part.objects.filter(q_user).order_by('-pub_date')

q_userはQオブジェクトであり、必要なのは3つのテーブルのすべての結果を並べ替えることです。「pub_date」フィールドを使用します。

この種のクエリを単純化するにはどうすればよいですか?

4

1 に答える 1

2

B_PhotoB_ActivityそしてB_Part同じテーブル構造を持っていませんよね?3つの異なるテーブルでクエリを作成することはできないと思います。UNIONはこれを行うことができますが、すべてのサブクエリが同じ構造のデータを返す必要があります。

写真、アクティビティ、パーツを組み合わせたタイムラインを表示したいようです。最も合理的な方法は、Pythonで結果を並べ替えることです。

bphoto = B_Photo.objects.filter(q_user).order_by('-pub_date')
bactivity = B_Activity.objects.filter(q_user).order_by('-pub_date')
bpart = B_Part.objects.filter(q_user).order_by('-pub_date')

timeline = sorted(bphoto + bactivity + bpart, key=lambda x:x.pub_date)

アップデート:

意味がわかります。これらの3つのテーブルにデータが多すぎて、最新の20レコードのみを表示したい場合は、次のように3つのテーブルで生のUNIONSQLを実行できます。

cursor = connection.cursor()
cursor.execute("SELECT id, type FROM (
    SELECT id, 'photo' AS type, pub_date FROM b_photo UNION 
    SELECT id, 'activity' AS type, pub_date FROM b_activity UNION 
    SELECT id, 'part' AS type, pub_date FROM b_part) AS my_query
    ORDER BY pub_date DESC LIMIT 20")
results = cursor.fetchall()
# results will be something like ((id, type), (id, type), ...)
# where type indicates what the id is (photo, activity or part)

次に、individualB_XXX.objects.get(id=id)を使用して、の各オブジェクトを取得しますids

for result in results:
    if result[1] == 'photo':
        obj = B_Photo.objects.get(id=result[0])
    elif result[1] == 'activity':
        obj = B_Activity.objects.get(id=result[0])
    elif result[1] == 'part':
        obj = B_Part.objects.get(id=result[0])
    # do sth with obj...
于 2012-09-26T16:20:24.847 に答える