web-dev-qa-db-ja.com

Djangoモデルで使用される__init__関数の作成

モデルの1つに___init___関数を記述して、オブジェクトを作成できるようにしようとしています。

_p = User('name','email')
_

モデルを作成するとき、私は以下を持っています:

_def __init__(self, name, email, house_id, password):
    models.Model.__init__(self)
    self.name = name
    self.email = email
_

これは機能し、オブジェクトをデータベースに保存できますが、User.objects.all()を実行すると、___init___関数を取り出さない限り、何もプルアップしません。何か案は?

66
victor

Djangoの組み込み機能に依存し、名前付きパラメーターを渡すのが最も簡単な方法です。

p = User(name="Fred", email="[email protected]")

ただし、キーストロークを保存するように設定している場合は、初期化子をいじるのではなく、クラスに静的な便利なメソッドを追加することをお勧めします。

# In User class declaration
@classmethod
def create(cls, name, email):
  return cls(name=name, email=email)

# Use it
p = User.create("Fred", "[email protected]")
97
Baldu

Djangoは、モデルのコンストラクターの署名が(self, *args, **kwargs)、または合理的なファクシミリ。署名を完全に互換性のないものに変更すると、署名が破損します。

正しい答えは、__init__のオーバーライドを避け、 Django docs で説明されているようにクラスメソッドを記述することです。

しかし、これはあなたがしようとしているように行うことができます。*args, **kwargsに追加して__init__で受け入れ、それらをスーパーメソッド呼び出しに渡すだけです。

def __init__(self, name, email, house_id, password, *args, **kwargs):
        super(models.Model, self).__init__(self, *args, **kwargs)
        self.name = name
        self.email = email
16
austinheiman

Argsパラメーターを使用してモデルを作成しないでください。そのようなモデルを作成する場合:

 User('name','email')

ほとんどのモデルは初期化にそれ以上のものを必要とするため、非常に速く非常に読みにくくなります。あなたは非常に簡単に終わる可能性があります:

User('Bert', 'Reynolds', '[email protected]','0123456789','5432106789',....)

ここでのもう1つの問題は、「Bert」が名か姓かわからないことです。最後の2つの番号は、簡単に電話番号とシステムIDです。しかし、明示的でない限り、それらをより簡単に混ぜたり、識別子を使用している場合は順序を混ぜたりするでしょう。さらに、順序に基づいて実行すると、このメソッドを使用し、パラメーターの任意の順序を覚えていない他の開発者にさらに別の制​​約が課せられます。

代わりに次のようなものを好む必要があります。

User(
    first_name='Bert',
    last_name='Reynolds',
    email='[email protected]',
    phone='0123456789',
    system_id='5432106789',
)

これがテストなどの場合は、ファクトリを使用してモデルをすばやく作成できます。ファクトリーボーイのリンクは役に立つかもしれません: http://factoryboy.readthedocs.org/en/latest/

2
unflores