2017-02-23 3 views
0

私はどのように説明するために+5時間の訓練を受けています:Item.objects.values('type', 'state')は2つのキーだけを含む辞書を返します。djangoの値は異常な振る舞いをしますか?

ただし、Item.objects.values('type', 'state').annotate(nb=Count('id'))が動作します。

値関数によって返されない場合、id属性が存在することを通訳者がどのように知っていますか?

+0

「id」フィールドを指定しなかった場合は、問題はありません。fieldsパラメータを省略しない限り、指定したフィールドのみが返されます。https: //github.com/django/django/blob/master/django/db/models/query.pyそして最後の例をhttps://docs.djangoproject.com/en/1.10/ref/models/querysets/#で確認してください。値。あなたの最後の質問については、別の目的のために 'values'を使用しようとしているようです。 – chachan

答えて

1

Item.objects.values('type', 'state')は単なる辞書ではないため、id属性が存在することがわかります。 は、与えられたパラメータに基づいて辞書として自身を表すオブジェクトです。

の紙Aそれを呼びましょう、オブジェクトは一枚の紙であると想像:

id : 1 
type : cheese 
state : melted 

あなたはそれだけで、あなたに関連する部分を示すことによって作成され、そのオブジェクトの表現で呼び出したときに、あなたが実際に見ている何、Aの上に置く穴に一枚の紙のような紙B

████████████████████ 
████████████████████ 
+--------------------+ 
|type: cheese  | 
+--------------------+ 
+--------------------+ 
|state: melted  | 
+--------------------+ 

しかし、紙Aはそのまま、紙Bの下にまだあります。だからItem.objects.values('type', 'state').annotate(nb=Count('id'))が働いています:annotateがオブジェクトを見ると、それは実際に何を求めているのですか?です。それは外部の観察者には見えません。換言すれば、annotateは、A,ではなく、の用紙Bを調べます。

オブジェクトItem.objects.values('type', 'state')をユーザとシステムとで異なるように表現することにより、システムは、チェックする必要がある場合に備えてできるだけ多くの情報を保持することができます。 ORMモデルでは、データベースとデータベースの表現の間に矛盾が生じないように、これが一般的です。

+0

タイプ(Item.objects.values( 'type'、 'state'))は、 – user2080105

1

あなたのモデルは、バックグラウンドでIDを持っており、またDjangoのORMは、モデルの定義

DjangoのORMを認識している遅延ロードあり、その結果が呼び出される前に、それは文句を言わない、何も実行しません。ですから、注釈を呼んでいる瞬間にまだ辞書ではありません。それはまだオブジェクトです。あなたは、それは結果を求める瞬間に、それはデータベースにクエリをトリガし、

DjangoのORMは、この

SELECT type, state, count(id) as nb FROM items 
+0

私の質問は簡単です。もしあなたがモデルを持っていない辞書から呼び出された場合、どうすれば 'id'の存在を知ることができるでしょうか? – user2080105

+0

@ user2080105あなたのモデルはバックグラウンドでIDを持っていますが、Django ORMはあなたのモデル定義を認識しています。 – iklinac

+0

Django ORMは、結果が呼び出される前は何もありません。ですから、注釈を呼んでいる瞬間にそれはまだ辞書ではありません。まだORMオブジェクトです。 – iklinac

0

に類似してデータベースにクエリにこれを変換あなたの結果を返す最初のクエリの辞書ない復帰を行います2つのキーで。それどころか、それはValuesQuerySetを返します。そのクエリーセットの各要素は辞書です。

他のクエリセットと同様に、ValuesQuerySetはモデルとの接続を保持しているため、必要に応じて他の要素をクエリに追加できます。クエリ全体は、クエリセットが反復されるまで実行されません。

関連する問題