1. ホーム
  2. パイソン

[解決済み】Djangoのauto_nowとauto_now_add

2022-03-26 06:57:37

質問

Django 1.1用です。

私のmodels.pyには、このようなものがあります。

class User(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

行を更新するときに、私は取得します。

[Sun Nov 15 02:18:12 2009] [error] /home/ptarjan/projects/twitter-meme/django/db/backends/mysql/base.py:84: Warning: Column 'created' cannot be null
[Sun Nov 15 02:18:12 2009] [error]   return self.cursor.execute(query, args)

私のデータベースの該当箇所は

  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,

これは心配すべきことなのでしょうか?

余談ですが、私の管理ツールでは、この2つのフィールドは表示されません。これは想定内でしょうか?

解決方法は?

任意のフィールドに auto_now 属性が設定されている場合は、その属性も継承されます。 editable=False そのため、管理画面には表示されません。過去に、この問題を解決するために auto_now auto_now_add という引数はなくなりました。 カスタム save() メソッド .

そこで、これを正しく動作させるために、私は auto_now または auto_now_add を定義し、代わりに独自の save() メソッドで created が更新された場合のみ id が設定されていない場合 (たとえば、アイテムが最初に作成されたとき) は modified が保存されるたびに

私はDjangoを使って書いた他のプロジェクトで全く同じことをしたので、あなたの save() はこのようになります。

from django.utils import timezone

class User(models.Model):
    created     = models.DateTimeField(editable=False)
    modified    = models.DateTimeField()

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        if not self.id:
            self.created = timezone.now()
        self.modified = timezone.now()
        return super(User, self).save(*args, **kwargs)

これが役立つといいのですが

コメントに応じて編集します。

オーバーロードにこだわるだけの理由 save() これらのフィールド引数に依存するのとは、2つの点で異なります。

  1. 前述したように信頼性のアップダウンがあること。 これらの議論は、Django が対話する方法を知っているそれぞれのタイプのデータベースが日付/タイムスタンプフィールドをどう扱うかに大きく依存しており、リリースごとに壊れたり変わったりしているようです。(これが、日付/タイムスタンプフィールドを完全に削除するよう要求する原動力だと私は思っています)。
  2. DateField、DateTimeField、TimeField でのみ動作し、このテクニックを使用すると、アイテムが保存されるたびに任意のフィールドタイプに自動的に入力することができるという事実。
  3. 使用方法 django.utils.timezone.now() vs. datetime.datetime.now() というのは、TZを考慮した、あるいは素朴な datetime.datetime オブジェクトは settings.USE_TZ .

OPがなぜエラーを見たのかについてですが、正確には分かりませんが、以下のようになります。 created があるにもかかわらず、全く入力されていません。 auto_now_add=True . 私にとっては、これはバグであり、上記の小さなリストの1番目の項目を強調するものです。 auto_now そして auto_now_add は、せいぜい薄っぺらいものです。