7

Django には次のモデル継承構造があります。

class Parent(models.Model):
    # stuff

class A(Parent):
    # stuff

class B(Parent):
    # stuff

class C(Parent):
    # stuff

and the list goes on.

次のようなオブジェクトをフィルタリングするために、django-model-utils の InheritanceManager を使用しています。

Parent.objects.filter(foo=bar).select_subclasses()

これは、すべてのサブクラスをフィルタリングする場合にうまく機能します。私がやりたいのは、A オブジェクトと B オブジェクトをフィルター処理することですが、C オブジェクトはフィルター処理しません。次のような単一のクエリでこれを行いたい

Parent.objects.filter(foo=bar, __class__.__name__=A, __class__.__name__=B).select_subclasses()

そのようなフィルタリング操作を行うことは可能ですか?可能であればどのようにしますか?

4

3 に答える 3

0

通常、そのように継承可能に設定するのが最善とは考えられていません。これは、各 SQL クエリが結合を実行する必要があるためです。これにより、パフォーマンスが大幅に低下する可能性があります。パフォーマンスを向上させるために、abstractメタ値を使用できます。

class Parent(models.Model):
    # stuff
    class Meta:
        abstract = True

このように各テーブルは独立しているため、パフォーマンスが向上します。

それが当てはまらない場合、テーブル/モデル内のフィールドには、それらが配置されているテーブルの情報が含まれていないため、単一のクエリでそのようなことを行うことは不可能だと思います。その場合、何らかの方法でサブクラス化する必要がある可能性が最も高いInheritanceManagerですが、そこで何をすべきかわかりません。その場合、 content_types を使用すると役立つ場合があります。

それが大変な作業である場合は、いつでも簡単なハックを行うことができます (モンキー パッチのようなものです...)。私はそれがきれいではないことを知っていますが、うまくいきます:

class Parent(models.Model):
    # stuff
    table = models.CharField(max_length=8, default='parent')

class A(Parent):
    # stuff
    table = models.CharField(max_length=8, default='a')

class B(Parent):
    # stuff
    table = models.CharField(max_length=8, default='b')


# and then something like
# please note that I've never used django-model-utils
# so don't know the correct syntax
Parent.objects.filter(foo=bar, table__in=['parent', 'a']).select_subclasses()
于 2012-11-12T17:49:26.807 に答える