为什么添加__init __()方法会破坏我的Django模型? [英] Why does adding this __init__() method break my Django model?

查看:115
本文介绍了为什么添加__init __()方法会破坏我的Django模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是我之前提到的一个后续行动



  class MyModel(models.Model):
my_field1 = models.DateTimeField(default = datetime.utcnow,editable = False)
my_field2 = models.DateTimeField()

它的作品:

 >>> MyModel.objects.all()
[< MyModel:MyModel对象>< MyModel:MyModel对象>

现在我将以下构造函数添加到 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()
追溯(最近的最后一次调用):
文件< console>,第1行在< module>
在__repr__
data = list(self [:REPR_OUTPUT_SIZE + 1])中的文件MYvirtualenv / lib / python2.7 / site-packages / django / db / models / query.py
文件MYvirtualenv / lib / python2.7 / site-packages / django / db / models / query.py,第162行,__iter__
self._fetch_all()
文件MYvirtualenv /lib/python2.7/site-packages/django/db/models/query.py,第965行,在_fetch_all
self._result_cache = list(self.iterator())
文件MYvirtualenv /src/django-cache-machine-master/caching/base.py,第118行,__iter__
obj = iterator.next()
文件MYvirtualenv / lib / python2.7 / site- package / django / db / models / query.py,第255行,迭代器
obj = model_cls.from_db(db,init_list,row [model_fields_start:model_fields_end])
文件MYvirtualenv / lib / python2 .7 / site-packages / django / db / models / base.py,第489行,in_db
new = cls(* values)
TypeError:__init __()只需要1个参数)

为什么这发生在我添加相对简单的构造函数时?我应该如何补救?我需要该构造函数中的逻辑,所以我不能只是消除它。

尽管,强烈建议您使用 classmethod 或文档中的自定义管理器,您的代码将无法正常工作,因为您已修改超类的调用签名 ,应该是:

  super(MyModel,self).__ init __(* args,** kwargs)

您可以避免使用 classmethod p>

  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)
#用my_model
返回my_model

MyModel.sync_dates(some_date) doe你可以使用一个自定义的管理器,这是首选的方式:

 $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ do do do do do do do do do do do do do do do do do do do do do do do do do do do do do do do do do do do do do do do do do一些与my_model 
返回my_model

类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)


This question is a follow-up to one I asked earlier here.

I have a Django model as follows:

class MyModel(models.Model):
    my_field1 = models.DateTimeField(default=datetime.utcnow, editable=False)
    my_field2 = models.DateTimeField()

It works:

>>> MyModel.objects.all()
[<MyModel: MyModel object>, <MyModel: MyModel object>,

Now I add the following constructor to MyModel:

def __init__(self, **kwargs):
    super(MyModel, self).__init__(**kwargs)
    if self.my_field2 is None:
        self.my_field2 = self.my_field1

And that breaks the class:

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

Why does this happen when I add the relatively simple constructor? How should I remedy it? I need the logic in that constructor, so I cannot just eliminate it.

解决方案

Although, you're strongly advised to use a classmethod or a custom manager in the docs, your code would not work because you have modified the calling signature of the superclass, which should have been:

super(MyModel, self).__init__(*args, **kwargs)

You can avoid doing this by using a 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

And MyModel.sync_dates(some_date) does the trick.

Or you could use a custom manager which is the preferred way:

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()

And you can call MyModel.objects_synced.create_with_sync_date(some_date)

这篇关于为什么添加__init __()方法会破坏我的Django模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆