web-dev-qa-db-ja.com

Django ORM-objects.filter()vs. objects.all()。filter()-どちらが望ましいですか?

非常に頻繁に

_MyModel.objects.all().filter(...)
_

デフォルトのManangerのQuerySetを返します。最初はall()はかなり冗長なようです。なぜなら

_MyMode.objects.filter(...)
_

同じ結果をもたらします。

ただし、これはDjangoドキュメンテーションの次の2つのステートメントのため、デフォルトのマネージャーに対してのみ安全であると思われます。

「追加のマネージャーメソッドの追加」の章からの抜粋

カスタムManagerメソッドは、必要なものを返すことができます。 QuerySetを返す必要はありません。

all() managerメソッドの定義:

all()現在のQuerySet(またはQuerySetサブクラス)のコピーを返します。これは、モデルマネージャーまたはQuerySetのいずれかを渡して、結果をさらにフィルタリングする必要がある場合に役立ちます。いずれかのオブジェクトでall()を呼び出すと、間違いなく作業するQuerySetができます。

これは私には矛盾のように思えます。一方でDjango=は、マネージャーメソッドが任意のオブジェクトタイプを返すようにする自由を提供し、他方ではall()メソッドのQuerySetを必要とします。各マネージャーにはall()によって呼び出される_get_queryset_メソッドがありますが、カスタムマネージャーでall()をオーバーライドできないのは誰ですか?そうするには。

  • したがって、私が見る限り、all()メソッドはQuerySetを返すことを保証しません。 _MyModel.objects_は正確に何を返しますか?このステートメントはall()を呼び出しますか?または `get_queryset()?

  • MyModel.objects.filter(...)またはMyModel.objects.all().filter(...)を好みますか。もしそうなら、なぜですか?

  • 望ましくない方法でこれらのメソッドを台無しにする、不安定なマネージャーに遭遇したことがありますか?

37
Dr.Elch

Djangoソースコード でわかるように、マネージャーのall()メソッドはget_queryset()に委任するだけです。

_def all(self):
    return self.get_queryset()
_

そのため、ManagerからQuerySetを取得する方法にすぎません。 _MyModel.objects_はManagerを返すため、これはManagerではなくQuerySetを処理していることを確認するのに便利です。

たとえば、すべてのアイテムを繰り返し処理する場合、できません

_for item in MyModel.objects:
    # do something with item
_

マネージャーを反復処理できないためです。ただし、all()はQuerySetを返します。QuerySetを繰り返し処理するにはcanを使用します。

_for item in MyModel.objects.all():
    # do something with item
_

通常、all()を上書きしないでください。 get_queryset()を上書きできますが、このメソッドmustはQuerySetを返します。

filter()exclude()のようなフィルターメソッドを使用する場合は、既にQuerySetがあります これらのメソッドはQuerySetにプロキシされているため 。したがって、all().filter()のようなことをする必要はありません。

50
gitaarik
  1. _MyModel.objects_は、マネージャーインスタンスを返します。 all() return get_query_set()。すべてのオブジェクトが必要なときにすべてが揃っていると思います。
  2. 私はMyModel.objects.filter()が好きです。もう一方はもう1つのメソッド呼び出しであり、フィルターをかける場合はすべてのオブジェクトを必要としません:)
  3. 目的によって異なります。ただし、マネージャーの基本メソッドをオーバーライドする場合、同じ結果形式(QuerySetなど)を返します

Mymodel.objects.filter(username='abcd')は一致レコードのリストを提供しますMymodel.objects.get(pk='abcd')は主キー値に一致する単一レコードを返します

0
aarif faridi