ジャンゴモデルに対する少しの「倒錯」

怠azineは進歩のエンジン



時々、ジャンゴでモデルを作成すると、猿のように感じ始めます。 デフォルトでTrueまたはFalseを受け入れるenable属性を常に作成します。 オブジェクトマネージャーを単純なEnableManagerに変更しています。 そして、私はこれらの単調な操作を私のためにしたメカニズムを持ちたいです。 必要に応じて、それを行うことができます。





取得したいものを想像してください



私が思いついた最初の考えは、いくつかの抽象クラスを書くことでした(「mixin」を書くと、djangoモデルは設定したフィールドを追加しません)。必要に応じて接続します。 これはかなりオークの方法で、大量の繰り返しコードを生成しますが、これは望ましくありません。



次に、必要なクラスを作成する関数について考えました。 これにより、反復コードを大幅に節約でき、全体的に見た目は悪くありません。 「そして、どこかで、あなたのマネージャーを使う価値がないとしたらどうでしょう。これが唯一のケースですか?」 特別な機会のために、私はクラスを作りたくありません。 デコレータを使用する場合、これは回避できます。



合計:特定のパラメーターを使用して関数を作成する必要があります。





どこにも落とし穴があります



この場合、それはクラスの装飾でした。 実際には、デコレータでは、「@ foo」を使用して、完全なアクションがある場合にのみ転送できます。 しかし、デコレータにパラメータを渡すことができるようにする方法は?

実際、構文構成体「@」は2つの関数の合成として使用されます(g•f(x))。 python'eでは、関数とクラスの両方がオブジェクトであり、構文コンストラクト「@」の関数を返すことができます。 次のようなもの(l(y))•(f(x))、ここでl(y)-関数を返します。 デコレータコードは次のようになります。



def foo(cls=None, param="DefaultValue"): def decorator(cls): # do something with class return cls if cls is None: return decorator else: return decorator(cls)
      
      







login_requiredデコレータのdjangoでは、関数のみを備えた同様の何かが使用されます。



今、あなたはぶらぶらできる



すべての落とし穴はバラバラになっているようです。コードを書き始めることができます。



 def enable(cls=None, status=True, set_manager=True, mixin=False): ''' Adds enable field into cls or return mixin :param cls: class that would updates :param status: default value for enable field :type status: bool :param set_manager: sets if EnableManager is required :type set_manager: bool :param mixin: sets should be returned model mixin :type mixin: bool ''' def decorator(cls): ''' Adds field and manager if manager is required ''' cls.add_to_class('enabled', models.BooleanField(_('Enabled'), default=status)) if set_manager: cls.add_to_class('objects', EnableManager()) return cls class Class(models.Model): ''' Enable AbstractModels ''' enbaled = models.BooleanField(_('Enabled'), default=status) class Meta: abstract = True if cls and mixin: raise DecoratorMixinException elif mixin: if set_manager: Class.add_to_class('objects', EnableManager()) return Class elif cls: return decorator(cls) else: return decorator
      
      







DecoratorMixinExceptionは、パラメーターmixin = Trueの関数をデコレーターとして呼び出すことができないことを示す例外です。



マネージャーを追加するには、djangoモデルの機能であるadd_to_class()メソッドを使用します。classobjects = YourManager()またはcls.objects = YourManager()で記述した場合、機能しません。 同じ方法で、必要なフィールドをモデルに追加します。



使用例



 EnableFalseMixin = enable(status=false, mixin=True) class SimpleModel(EnableFalseMixin, models.Model): ''' Simple model ''' # some field here @enable class TestFalseEnable(models.Model): ''' Test enable ''' # some fields here @enable(status=false) class TestFalseEnable(models.Model): ''' Test enable ''' # some fields here
      
      







この記事は、毎日使用できる便利なメカニズムを作成する例として考案されました。

誰かがそれを役に立つと思うことを願っています djangoフレームワークでの開発をお楽しみください。



PS

気配りのある人は、「Enable」機能の名前が大文字になっていると誓うようです。これはPEP8に対応していません。 これは、この関数が新しいクラスを生成するためです。 pythonとdjangoを習得してください。これはどの程度正しく行われますか? 私はいくつかのプロジェクトでこれに会いましたが、どれほど正しいかについては考えませんでした。




All Articles