2

A と B の 2 つの単純なモデルがあります。

from django.db import models

class A(models.Model):
  name = models.CharField(max_length=10)

class B(A):
  age = models.IntegerField()

では、B のインスタンスを持たない A のすべてのインスタンスを照会するにはどうすればよいでしょうか?

私が見つけた唯一の方法は、各サブクラスに NOT NULL である明示的に一意のフィールドを必要とするため、たとえば A.objects.filter(b__this_is_a_b=None) を実行して、B インスタンスでもないインスタンスを取得できます。そのような明示的なばかげたフラグを追加せずにこれを行う方法を探しています。

また、すべてのオブジェクトに対してクエリを実行してから、Python でそれらをフィルター処理したくもありません。DBにそれをさせたいのですが、これは基本的に次のようなものですSELECT * FROM A WHERE A.id in (SELECT id from B)

4

3 に答える 3

2

django または python の一部のバージョン以降、これも同様に機能します。

A.Objects.all().filter(b__isnull=True)

a が A オブジェクトである場合、ab は a のサブクラス B を与えるため、それが存在する場合

私はこれが古い質問であることを知っていますが、私の答えはこの主題に関する新しい検索者に役立つかもしれません.

以下も参照してください。

マルチテーブル継承

これに関する私自身の質問の 1 つは、スーパー クラスをサブ クラスにダウンキャストすることです。

于 2012-05-30T20:50:32.813 に答える
1

単一のクエリで、Django の ORM を使用して DB でこれを純粋に実行できるかどうかはわかりません。これが私ができる最高のことです:

A.objects.exclude(id__in=[r[0] for r in B.objects.values_list("a_ptr_id")])

これは 2 つの DB クエリであり、単純な継承グラフで最もうまく機能します。A の各サブクラスには、新しいデータベース クエリが必要です。


さて、それは多くの試行錯誤を要しましたが、私には解決策があります. それはまったく醜く、SQL はおそらく 2 つのクエリを使用するよりも悪いですが、次のようなことができます。

A.objects.exclude(b__age__isnull=True).exclude(b__age_isnull=False)

b のフィールドを参照せずに Django に結合させる方法はありません。しかし、これらの連続する.exclude()s を使用すると、B サブクラスを持つ A をいずれかの除外に一致させます。残っているのは、B サブクラスのない A だけです。

とにかく、これは興味深い使用例です。django-dev で取り上げる必要があります...

于 2009-02-26T15:57:12.983 に答える