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

时间:2009-05-09 16:23:36

标签: python django django-models

我正在尝试为我的某个模型编写__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__函数,否则它不会提取任何内容。有什么想法吗?

4 个答案:

答案 0 :(得分:96)

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

p = User(name="Fred", email="fred@example.com")

但如果您已经设置了一些按键保存,我建议在类中添加静态便捷方法,而不是弄乱初始化器。

# 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")

答案 1 :(得分:41)

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

答案 2 :(得分:13)

正确的答案是避免覆盖__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

答案 3 :(得分:2)

不要使用args参数创建模型。如果你制作这样的模型:

 User('name','email')

由于大多数模型需要的不仅仅是初始化,因此它变得非常难以理解。你可以很容易地结束:

User('Bert', 'Reynolds', 'me@bertreynolds.com','0123456789','5432106789',....)

这里的另一个问题是你不知道'Bert'是第一个还是姓氏。最后两个数字可以很容易地是电话号码和系统ID。但如果没有明确表示,您将更容易混淆它们,或者如果您使用标识符则混淆订单。更重要的是,基于顺序执行操作会对使用此方法的其他开发人员施加另一个约束,并且不会记住参数的任意顺序。

你应该更喜欢这样的东西:

User(
    first_name='Bert',
    last_name='Reynolds',
    email='me@bertreynolds.com',
    phone='0123456789',
    system_id='5432106789',
)

如果这是用于测试或类似的测试,您可以使用工厂快速创建模型。工厂男孩链接可能很有用:http://factoryboy.readthedocs.org/en/latest/