这个问题是我之前提到的问题的后续问题here。
我有一个Django模型如下:
class MyModel(models.Model):
my_field1 = models.DateTimeField(default=datetime.utcnow, editable=False)
my_field2 = models.DateTimeField()
有效:
>>> MyModel.objects.all()
[<MyModel: MyModel object>, <MyModel: MyModel object>,
现在我将以下构造函数添加到MyModel
:
def __init__(self, **kwargs):
super(MyModel, self).__init__(**kwargs)
if self.my_field2 is None:
self.my_field2 = self.my_field1
这打破了班级:
>>> MyModel.objects.all()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "MYvirtualenv/lib/python2.7/site-packages/django/db/models/query.py", line 138, in __repr__
data = list(self[:REPR_OUTPUT_SIZE + 1])
File "MYvirtualenv/lib/python2.7/site-packages/django/db/models/query.py", line 162, in __iter__
self._fetch_all()
File "MYvirtualenv/lib/python2.7/site-packages/django/db/models/query.py", line 965, in _fetch_all
self._result_cache = list(self.iterator())
File "MYvirtualenv/src/django-cache-machine-master/caching/base.py", line 118, in __iter__
obj = iterator.next()
File "MYvirtualenv/lib/python2.7/site-packages/django/db/models/query.py", line 255, in iterator
obj = model_cls.from_db(db, init_list, row[model_fields_start:model_fields_end])
File "MYvirtualenv/lib/python2.7/site-packages/django/db/models/base.py", line 489, in from_db
new = cls(*values)
TypeError: __init__() takes exactly 1 argument (2 given)
为什么在添加相对简单的构造函数时会发生这种情况?我该如何补救呢?我需要构造函数中的逻辑,所以我不能消除它。
答案 0 :(得分:2)
尽管强烈建议您在文档中使用classmethod
或自定义管理器,但由于您修改了superclass
的调用签名,因此您的代码无效:
super(MyModel, self).__init__(*args, **kwargs)
您可以使用classmethod
:
class MyModel(models.Model):
my_field1 = models.DateTimeField(default=datetime.utcnow, editable=False)
my_field2 = models.DateTimeField()
@classmethod
def sync_dates(cls, myfield1):
my_model = cls(my_field1=myfield1, my_field2=myfield1)
# do something with my_model
return my_model
MyModel.sync_dates(some_date)
可以解决这个问题。
或者您可以使用自定义管理器,这是首选方式:
class MyModelManager(models.Manager):
def create_with_sync_date(self, myfield1):
my_model = self.create(my_field1=myfield1, my_field2=myfield1)
# do something with my_model
return my_model
class MyModel(models.Model):
my_field1 = models.DateTimeField(default=datetime.utcnow, editable=False)
my_field2 = models.DateTimeField()
objects_synced = MyModelManager()
您可以致电MyModel.objects_synced.create_with_sync_date(some_date)
答案 1 :(得分:0)
您不需要在Django模型中使用__init__
,而是使用Meta
类
class MyModel(models.Model):
my_field1 = models.DateTimeField(default=datetime.utcnow, editable=False)
my_field2 = models.DateTimeField()
class Meta:
verbose_name = 'My Model'
verbose_name_plural = 'My Models' # and so on
答案 2 :(得分:0)
不建议使用 init 。 根据Django的文档:
https://docs.djangoproject.com/en/1.9/ref/models/instances/#creating-objects
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
@classmethod
def create(cls, title):
book = cls(title=title)
# do something with the book
return book
book = Book.create("Pride and Prejudice")