0

Django 1.5の時点で、カスタム機能を追加するためにユーザーモデルをサブクラス化するための組み込みのサポートがありますが、互換性に関する考慮事項がいくつかあります。1.5より前は、サブクラス化は非常に面倒でした。ただし、特にメソッド.full_name()の形式で、必要な機能がいくつかあります。first + " " + middle + " " +lastこれにより、ユーザーの名前が返されます。より一般的には、適切な場所にのみスペースを配置し、ミドルネームを処理できますが、モデルにミドルネームが含まれている必要はありません。

これで、Userのサブクラスではなく、models.pyの上部に次のように表示されます。

def full_name(self):                                    # Here's a useful full_name method
    '''Return the full name of an object, or else an empty string. Can be applied to objects with first_name, last_name and optionally middle_name fields'''
    fullname = self.first_name
    try:
        self.middle_name
    except AttributeError:                          # this type of object might not have a middle_name field
        pass
    else:                                           # If it has a middle_name field, append it with a conditional space
        if(self.first_name and self.middle_name):
            fullname += " "
        fullname += self.middle_name
    if(fullname and self.last_name):                # if fullname has stuff in it now, we'll need a space.
            fullname += " "
    fullname += self.last_name
    return fullname
User.full_name = full_name                              # Bless the User model with our full_name function

私は一般的にPythonに比較的慣れていないので、これが機能することを非常に嬉しく思います。この同じ関数を他のいくつかのモデルに使用することで、少し時間を節約できました(models.pyのクラス定義でfull_name = full_nameを説明するだけです)。おそらく今では、middle_name機能の方が理にかなっています。他のモデルにはミドルネームがあります。

私の質問は、この慣習とサブクラス化について本質的に何か悪いことや悪いことはありますか?おそらく主な欠点は、この方法でモデルにフィールドを追加できなかったことです。しかし、それはそれですか?このメソッドの追加は、アプリの残りの部分、およびユーザーをインポートする他のモジュール全体で持続するように見えます(具体的には、テンプレートは期待どおりに機能します)。

基本的に、これはより多くの機能が必要であるという私の問題を解決するための非常に巧妙でエレガントな方法だと思いますが(私は確かに斬新ではありませんが)、後で戻ってきて私を噛むのでしょうか?

詳細:私が尋ねる理由の1つは、関係を持ついくつかのユーザーロール(Painter、Clerk、およびManagerと呼びましょう)があるmodels.ForeignKey(User, blank=True)ことです。したがって、たとえば、User.painterはPainterロールを返す場合がありますが、ユーザーが実際にはペインターでない場合は、ObjectNotFound例外を発生させる可能性もあります。try:except:ステートメントでコードを散らかすのではなく、上記のアイデアの使用を拡張して、たとえば.is_painter()メソッドと.is_manager()メソッドをUserに追加して、少し試行する代わりにifステートメント:except:どこでも混乱します。

4

1 に答える 1

1

これはモンキーパッチと呼ばれます。お世辞にもならない名前から集めたかもしれませんが、必ずしも好意的に見られているわけではありません。Pythonコミュニティでは、これは一般的な手法ではなく、通常、他に選択肢がない場合に備えて予約されています。あなたはあなたが望むものを達成するための適切なインターフェース(サブクラス化)を持っているので、それは避けるのが最善です。

モンキーパッチは壊れやすく、変更するモジュールが変更された場合に破損する可能性があります。コードが実際にどこにあるかは必ずしも明らかではないため、他の誰かが後で変更/デバッグするのは難しい場合があります。

とは言うものの、それがすでに存在し、機能している場合は、それを維持することができます。誰もあなたを追跡し、暗い路地であなたを殴るつもりはありません。

于 2013-03-20T21:09:05.453 に答える