编写__init__函数以在django模型中使用

vic*_*tor 68 python django django-models

我正在尝试为__init__我的一个模型编写一个函数,以便我可以通过执行来创建一个对象

p = User('name','email')
Run Code Online (Sandbox Code Playgroud)

当我写模型时,我有

def __init__(self, name, email, house_id, password):
    models.Model.__init__(self)
    self.name = name
    self.email = email
Run Code Online (Sandbox Code Playgroud)

这是有效的,我可以将对象保存到数据库中,但是当我执行'User.objects.all()'时,除非取出我的User.objects.all()功能,否则它不会提取任何内容.有任何想法吗?

Bal*_*ldu 100

依靠Django的内置功能并传递命名参数将是最简单的方法.

p = User(name="Fred", email="fred@example.com")
Run Code Online (Sandbox Code Playgroud)

但是如果你打算保存一些键击,我建议在类中添加静态便捷方法而不是搞乱初始化器.

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

# Use it
p = User.create("Fred", "fred@example.com")
Run Code Online (Sandbox Code Playgroud)

  • @classmethod on create也更好 (4认同)
  • 是的,工厂方法是去这里的方法.您也可以考虑将其放在Manager上.搞乱构造函数签名肯定会破坏事物. (2认同)

Ign*_*ams 43

Django期望模型的构造函数的签名是(self, *args, **kwargs)或者一些合理的传真.您将签名更改为完全不兼容的内容已经破坏了它.

  • 从Django 2.1开始,Ignacio的答案是正确的,应该被接受.直接从2.1文档中,他们说"你可能会试图通过覆盖__init__方法来定制模型.但是,如果这样做,请注意不要更改调用签名,因为任何更改都可能阻止模型实例被保存.来自:https://docs.djangoproject.com/en/2.1/ref/models/instances/ (4认同)

aus*_*man 17

正确的答案是避免覆盖__init__并编写Django文档中描述的类方法.

但这可以像你正在尝试一样完成,你只需要添加*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
Run Code Online (Sandbox Code Playgroud)

  • super(models.Model,self).__ init __(*args,**kwargs) (5认同)
  • `super(<YourModelName>, self).__init__(*args, **kwargs)` (2认同)