2

私は次の2つのモデルを持っています:

class JobPosition(models.Model):
    job = models.ForeignKey(Job, related_name='positions')
    position = models.ForeignKey('userprofile.Position')
    date_added = models.DateTimeField()
    end_date = models.DateTimeField()

class ExternalJob(models.Model):
    name = models.CharField(max_length=256)
    position = models.ForeignKey('userprofile.Position') 
    date_added = models.DateTimeField()
    end_date = models.DateTimeField()

基本的に以下を1つのQSに組み合わせて、クエリセットを連結するにはどうすればよいですか?

internal_jobs = JobPosition.objects.filter(end_date__gte=datetime.now())
external_jobs = ExternalJob.objects.filter(end_date__gte=datetime.now())
all_jobs = (internal_jobs + external_jobs).order_by('-date_added')
4

2 に答える 2

1

まず、この同様の質問が役立つかどうかを確認します。djangoを使用して、別々のモデルからの2つのクエリを1つのクエリに組み合わせるにはどうすればよいですか?。これは、別のSQLステートメントを追加するために実行する必要のあるアプローチである可能性があります(SQL側で要求していることを実行できるかどうかはわかりませんが)

達成したいのがこれら2つのクエリセットの遅延評価の組み合わせだけである場合は、itertools.chainを使用できます。

from itertools import chain

combined = chain(internal_jobs, external_jobs)
# combined is a generator that will iterate over your combined
# iteratables
for result in combined:
    # do something

最終的な日付の並べ替えについては、クライアント側でこれを行う必要があるかもしれません。呼び出しを行うと、完全なクエリセットリストが評価されますsorted

from operator import attrgetter

combined = chain(internal_jobs, external_jobs)
for result in sorted(combined, key=attrgetter("date_added"), reverse=True):
    # do something
于 2012-04-08T01:56:07.760 に答える
0

アップデート

Djangoビューで2つ以上のクエリセットを組み合わせる方法を見つけましたか? 、通常の場合の参照


パフォーマンスが重要で、結果が反復子として使用される場合、以下はjdi によって投稿されたリンクのhttps://stackoverflow.com/a/313149/165603の単純なバージョンです。

def merge_by_latest_date_added(*querysets):
    querysets = [[qs, None] for qs in querysets]

    def iterator_helper():
        for qs_v in querysets[:]:
            qs, v = qs_v
            if v is not None:
                continue
            try:
                qs_v[1] = qs.next()
            except StopIteration:
                querysets.remove(qs_v)
        return querysets

    while iterator_helper():
        qs_v = max(querysets, key=lambda x:x[1].date_added)
        yield qs_v[1]
        qs_v[1] = None

あなたはそれからすることができます

internal_jobs = internal_jobs.order_by('-date_added').iterator()
external_jobs = externals_jobs.order_by('-date_added').iterator()
all_jobs = merge_by_latest_date_added(internal_jobs, external_jobs)

psycopg2 などの DB バックエンドの場合、トリックを使用してクエリセットをラップし、メモリ フットプリントを削減することができます。

ステートメント内のコードを分離whileして、マージ関数を一般的なバージョンにすることもできます。たとえば、実際にPKを共有する大きなクエリセットを処理するために使用しました。

于 2012-04-08T09:06:44.350 に答える