2016-08-12 13 views
1

私はDjango REST FrameworkでWebアプリケーションを構築します。単純なビューがあり、dbフィールドで参照情報を返します。
resources.py:DjangoでのVIEW評価の理解

RESOURCES = { 
    'genres': GenreSerializer(Genre.objects.all(), many=True).data, 
    'authors': AuthorSerializer(Author.objects.all(), many=True).data, 
    ...... 
    } 


class ResourceApiView(views.APIView): 

    def get(self, request): 
     params = request.query_params 
     response_dict = {} 
     if params: 
     # Return RESOURSES based on query params 
      for i in params: 
       q = RESOURCES.get(i) 
       if q: 
        response_dict[i] = q 
     else: 
     # Return all RESOURSES 
      response_dict = RESOURCES 
     return Response(response_dict, 
         status=status.HTTP_200_OK 
         ) 

それは正常に動作しますが、私は1つのリソースのクエリセットに新しいオブジェクトを追加するとき。何も起こらず、古いクエリが表示されます。
RESOURSESを私のモジュールに印刷しようとしましたが、それは一度印刷され、他のget要求はそれを引き起こさない。
次にをクラスResourceApiViewに直接移動し、モジュール内でRESOURSESと同じように動作します。

class ResourceApiView(views.APIView): 

    RESOURCES = { 
     'genres': GenreSerializer(Genre.objects.all(), many=True).data, 
     'authors': AuthorSerializer(Author.objects.all(), many=True).data, 
     ...... 
     } 

    def get(self, request): 
     ... 

それは私がget方法でRESOURSESを入れたときにのみ正常に動作します。

class ResourceApiView(views.APIView): 

    def get(self, request): 
     RESOURCES = { 
      'genres': GenreSerializer(Genre.objects.all(), many=True).data, 
      'authors': AuthorSerializer(Author.objects.all(), many=True).data, 
      ...... 
      } 

しかし、どうしてですか?なぜ各メソッド呼び出しのクラス属性からクエリを評価できないのですか?

+1

あなたの 'RESOURCES'はサーバが起動するときにのみ評価され、一方、あなたが 'get'メソッドにそれを置くと、要求ごとに評価されます。これは、あなたが 'queryset'属性と' get_queryset'メソッドを持っている理由です – dnit13

答えて

2

これは、djangoよりもPythonに関連しています。あなたがHAVA lib.py

def say_hello(): 
    print "hello" 

GREETINGS = { 
    "hello": say_hello() 
} 

は今、別のPythonのファイル(またはシェル)に移動し、ちょうどあなたがファイルをインポートするときには、解決を開始するので、あなたのlib.pyは、コンソールに「hello」を印刷しますインポートファイルとしましょうその中にGREETINGS変数(あなたの場合はRESOURCES)を作成し、say_hello()メソッドを呼び出すと、クエリが実行されます。しかし、pythonは十分にスマートなので、ファイルを再びインポートすると、以前にインポートしたことを覚えているので、モジュールを再度ロードする必要はありません。すでにモジュール参照が保存されているためです。

あなたのクエリは、同じクラスの属性などのリソースを配置するための文句を言わないの参照変更を行う

ビューが最初にロードされたときに一度だけ実行、およびビューを再インポートbeeingてさ。コードはクラスがインポートされたときに実行された、これは明確に:)多分ドキュメントは、それを説明する

希望を(再び、あなたはlib.py例にクラスを作成してテストすることができます)より良いhttps://docs.python.org/2/tutorial/modules.html

注: シリアライザの.dataが実際にクエリを実行していると思います。それがなければ、ORMは怠惰なので、クエリとシリアライザは参照として格納されます。 1つのリソース(例えば 'authors')を依頼してもすべてのクエリ( 'authors'、 'genres'など)を依頼した場合、エンドポイントのパフォーマンスを向上させるためにリソースを変更してください。