1

オブジェクト作成の成功メッセージを表示するデコレータを作成しました。

from django.contrib import messages

def success_message(klass):
    def form_valid(self, form):
        response = super(klass, self).form_valid(form)
        messages.success(self.request, 'Object added successfully')
        return response

    klass.form_valid = form_valid
    return klass

クラスベースのジェネリックビューを装飾するために使用します。

@success_message
class BandCreateView(CreateView):
    model = Band

ここで、デコレータをパラメータ化して、これが可能になるようにします。

@success_message('Band created successfully.')
class BandCreateView(CreateView):
    model = Band

どうすればいいのですか?messageにパラメータを追加しようとしましsuccess_messageたが、コンパイラがパラメータ数の不一致について文句を言ったので、別の方法があるはずだと思います。

4

3 に答える 3

3

クロージャを使用する必要があるようです。

def decorator(arg):
    def wrap(klass): ...
    return wrap

あなたの呼び出しはに評価されるので

class BandCreateView(CreateView): ...
BandCreateView = @success_message('Band created successfully.')(BandCreateView)

ダブルコールに注意してください

于 2011-09-29T00:09:57.463 に答える
1

以前はこの種のことをミックスインとして実行していましたが、デコレータの方が理にかなっています(クラスに追加する手間が少し少なくなります)。デコレータにメッセージを渡す必要をなくすために、次のようなフォームインスタンスの詳細な名前を取得することをお勧めします。

from django.utils.translation import ugettext_lazy as _

def ucfirst(value):
    return value[0].upper() + value[1:]

def success_message(klass):
    __orig_form_valid = klass.form_valid
    def form_valid(self, form):
        response = __orig_form_valid(self, form)
        messages.success(self.request, _("%(object)s \"%(object_name)s\" was saved successfully.") %
                         {'object': ucfirst(form.instance._meta.verbose_name), 'object_name': unicode(form.instance)})
        return response

    klass.form_valid = form_valid
    return klass

これにより、次のような成功メッセージが生成されます。

お客様「ACMEInc。」正常に保存されました。

于 2012-02-28T12:06:58.687 に答える
0

TL; DR

パラメータレスデコレータはclass -> class関数として宣言されています。
パラメータを持つデコレータは、高階args -> (class -> class)関数として宣言されています。

パラメータを受け取り、クラスを受け取り、クラスを返す関数(つまり、「単純な」デコレータ)を返します。

説明

t.dubrownikによる関連スレッドからの回答は、文字通り私を救いました。

とにかく、引数を持つデコレータの構文は少し異なります。<strong>引数を持つデコレータは、関数を受け取り、別の関数を返す関数を返す必要があります。したがって、実際には通常のデコレータが返されるはずです。

彼は関数デコレータについて話していますが、この概念はクラスデコレータにも適用できます。
これが私が得たものです:

from django.contrib import messages

def success_message(message):
    def actual_decorator(klass):
        def form_valid(self, form):
            response = super(klass, self).form_valid(form)
            messages.success(self.request, message)
            return response

        klass.form_valid = form_valid
        return klass

    return actual_decorator

actual_decoratorそれ自体がのパラメータなしバージョンをどのように繰り返すか、そしてその戻り値が関数自体であるため、success_messageどのようsuccess_messageに高階関数になったかに注意してください。

于 2011-09-29T00:09:35.000 に答える