6

djangoでクラスベースのビューを使い始めたところです。しかし、私を混乱させる問題があります。マルチスレッド開発サーバーを使用して、django1.4.1で次のコードスニペットを実行しました。

class TestView(TemplateView):
    template_name = 'test.html'
    count = 0
    mylist = [1, ]

    def get(self, request, *args, **kwargs):
        self.count += 1
        self.mylist.append(self.mylist[-1] +1)
        context = self.get_context_data(**kwargs)
        return self.render_to_response(context)

    def get_context_data(self, **kwargs):
        context = super(TestView, self).get_context_data(**kwargs)
        context['count'] = self.count
        context['mylist'] = self.mylist
        return context

テンプレートは、コンテキスト変数countとmylistを出力するだけです。このビューが呼び出されると、たとえば最大5回、出力は次のようになります。

count: 1
mylist: [1, 2, 3, 4, 5, ]

そして今、私は混乱しています。djangoのドキュメントによると、各リクエストには独自のクラスインスタンスがあります。

では、mylistを複数のリクエストに拡張するにはどうすればよいでしょうか。count変数がインクリメントされなかったのはなぜですか?

4

3 に答える 3

1

複数のリクエストで利用できるものが必要な場合は、それをセッションに追加する必要があります。ivar はそのための場所ではありません。スレッド セーフのため、このas_viewメソッドは毎回クラスの新しいインスタンスを返します。これは、同じクラスの他のインスタンスで発生した他のことによって影響を受けることはありません。これは仕様によるものであり、そうでない場合は多くの問題が発生します。

于 2012-08-16T20:01:26.057 に答える
0

要求ごとに、ビューが作成されて新たに呼び出されますが、以前のビューに関する知識はありません。複数のビューにわたって情報を保持するには、永続ストレージに格納する必要があります。これは通常、Django では、長期ストレージが必要な場合はデータベース、短期永続性にはセッションを意味します。

getまた、 (and post)をオーバーライドする必要はほとんどありません。get_context_dataそこで行ったすべてのことは、メソッドで行うことができます。

于 2012-08-17T19:53:07.067 に答える
0

リストは変更可能です。int は不変です

リストに追加できますが、それはクラスの同じ参照のままです。しかし、self.count += 1そうすると、毎回新しい int オブジェクトが作成され、それがそのインスタンスのスコープになります。値がクラスに影響を与えることはありません。

たとえば、次のように設定するとします。

count = [0]

def get(self):
    self.count[0] += 1

リストのメンバーを変更していて、毎回オブジェクトを置き換えていないため、インスタンス間でカウントが増加することがわかります。その容器をお勧めするわけではありません。ほんの一例です。

次のようにして、クラスを直接変更することができます。

count = 0

def get(self):
    self.__class__.count += 1

これにより、毎回クラス レベルで int オブジェクトが置き換えられます。

しかし、このようにスレッド間でクラスのデータを永続化しようとすると、非常に注意が必要です。スレッドセーフではありません。読み取り専用データには実際には問題はありませんが、多数の異なるスレッドから変更すると問題が発生する可能性があります。データをデータベースに保存すると、はるかに優れたものになります。

于 2012-08-16T19:35:38.537 に答える