2016-06-14 15 views
0

この質問は私が以前に尋ねたもののフォローアップですhereこの__init __()メソッドを追加すると、私のDjangoモデルが破損するのはなぜですか?

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

それは動作します:次のように

私はDjangoのモデルを持っている今

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

I追加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) 

比較的シンプルなコンストラクタを追加するとどうなりますか?どのように私はそれを改善する必要がありますか?私はそのコンストラクタのロジックが必要なので、ただそれを排除することはできません。

+2

を呼び出すことができます。あなたはそれを消毒するのを忘れましたか、実際に間違ったクラスを偶然に呼んでいますか? – Anonymous

+4

あなたはargsが不足しているように思えます。 def __init __(自己、* args、** kwargs) – Dean

+0

@Anonymous。はい。それは衛生上の誤りでした。ごめんなさい。今修正されました。 –

答えて

0

あなたはのinitを使用して

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 
+0

これは私が示した '__init __()'メソッドと同じ機能を実現しません。 –

0

が推奨されMetaクラスを使用する代わりに、Djangoのモデルで__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") 
1

あなたが強くドキュメントでclassmethodまたはカスタムマネージャを使用することをお勧めしている、が、あなたが呼び出して署名を変更したので、あなたのコードは動作しません

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

あなたはclassmethodを使用してこれを行うことを避けることができます:

をされている必要があります superclass
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`が、コンストラクタで` Prediction`持っMyModel.objects_synced.create_with_sync_date(some_date)

関連する問題