86

私はこのような2つのモデルを持っています:

class User(models.Model):
    email = models.EmailField()

class Report(models.Model):
    user = models.ForeignKey(User)

実際には、各モデルには、この質問には関係のないフィールドがさらにあります。

「a」で始まる電子メールを持ち、レポートを持たないすべてのユーザーをフィルター処理したいと考えています。他の分野に基づくより多く.filter()の基準があります。.exclude()

私は次のようにアプローチしたい:

users = User.objects.filter(email__like = 'a%')

users = users.filter(<other filters>)

users = ???

をお願いします ???レポートが関連付けられていないユーザーを除外します。どうすればいいですか?私が提示したようにこれが不可能な場合、代替アプローチは何ですか?

4

7 に答える 7

114

注: この回答は、Django 1.5 向けに 2013 年に作成されました。新しいバージョンの Django で動作するより良いアプローチについては、他の回答を参照してください。

を使用しisnullます。

users_without_reports = User.objects.filter(report__isnull=True)
users_with_reports = User.objects.filter(report__isnull=False).distinct()

を使用する場合isnull=Falsedistinct()結果の重複を防ぐために が必要です。

于 2013-02-12T11:58:26.627 に答える
12

追加のクエリや JOIN を使用せずにネイティブ SQL EXISTS/NOT EXISTS を取得する唯一の方法は、それを .extra() 句に生の SQL として追加することです。

users = users.extra(where=[
    """NOT EXISTS(SELECT 1 FROM {reports} 
                  WHERE user_id={users}.id)
    """.format(reports=Report._meta.db_table, users=User._meta.db_table)
])

実際、これは非常に明白で効率的な解決策であり、なぜルックアップとして Django に組み込まれなかったのか疑問に思うことがあります。また、サブクエリを絞り込んで、先週のレポートがない[out]、または未回答/未閲覧のレポートがない[out]ユーザーのみを検索することもできます。

于 2016-08-10T17:41:23.490 に答える
1

レポートが関連付けられていないユーザーをフィルタリングするには、次のことを試してください。

users = User.objects.exclude(id__in=[elem.user.id for elem in Report.objects.all()])

于 2013-02-12T11:55:21.273 に答える