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