0
0

More than 3 years have passed since last update.

DjangoでDateFieldにdefault=timezone.nowと書いてしまった

Last updated at Posted at 2020-08-19

こんにちは、Densyakunです。

しばらく放置していたアプリケーションの開発を再開したので推測ですが、
DjangoでDateFieldにdefault=timezone.nowと書いてしまったのが原因だと思います。

何がしたかったのか
  • 日付のみを扱いたい
  • 値を無しにできるようにしたい
  • 入力しやすくするため、初期値を今日にしたい (auto_系は強制なので目的と違う)
環境
  • Windows 10 Pro
  • Python 3.7.7
  • pip 20.2.1
  • Django 3.0.7

絶対に書いてはいけないコード

from django.db import models
from django.utils import timezone

class Production(models.Model):
    first_date = models.DateField(default=timezone.now)

エラー

Django、sqlite3の内部エラーなので、バグだと思います。

Traceback (most recent call last):
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\exception.py", line 34, in inner       
    response = get_response(request)
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\base.py", line 156, in _get_response   
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\base.py", line 154, in _get_response   
    response = response.render()
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\template\response.py", line 106, in render
    self.content = self.rendered_content
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\template\response.py", line 83, in rendered_content  
    content = template.render(context, self._request)
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\template\backends\django.py", line 61, in render     
    return self.template.render(context)
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\template\base.py", line 171, in render
    return self._render(context)
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\template\base.py", line 163, in _render
    return self.nodelist.render(context)
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\template\base.py", line 937, in render
    bit = node.render_annotated(context)
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\template\base.py", line 904, in render_annotated     
    return self.render(context)
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\template\defaulttags.py", line 308, in render        
    if match:
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\query.py", line 272, in __bool__
    self._fetch_all()
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\query.py", line 1186, in _fetch_all        
    self._result_cache = list(self._iterable_class(self))
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\query.py", line 54, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\sql\compiler.py", line 1065, in execute_sql
    cursor.execute(sql, params)
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 100, in execute
    return super().execute(sql, params)
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\sqlite3\base.py", line 298, in execute
    return Database.Cursor.execute(self, query, params)
  File "C:\Users\densy\AppData\Local\Programs\Python\Python37\lib\sqlite3\dbapi2.py", line 64, in convert_date
    return datetime.date(*map(int, val.split(b"-")))
ValueError: invalid literal for int() with base 10: b'26 18:02:28.712485'

解決したい

データを使用したテンプレートページや、adminも見れなくなり、
シェルでProduction.objects.all()も使用できません(同じエラー)。
Production.objectsまでは問題ありません。

DateFieldはdateしか対応していませんが、
シェルで確認するとdatetimeになっていました。

一度、models.DateTimeField()に変更し、makemigrationsmigrateをしてから、
エラーが無くなり、確認すると時刻がありました。

次に、Djangoのshellを使って、手作業でデータを修正し、
その後、モデルをDateFieldにして、defaultはdatetime.date.todayにしましたが、無意味でした。
dateではタイムゾーンがなくなります。

from django.db import models
from datetime import date

class Production(models.Model):
    first_date = models.DateField(default=date.today)

makemigrationsmigrateを実行しましたが、直っていませんでした。

invalid literal for int() with base 10: b'25 15:00:00'
というエラーになり、時刻は変わっていましたが、
エラーは変わりませんでした。

また、私の場合値をなしにもしたかったので、
blank=True、null=Trueにしています。
これが原因か?と思いましたが、
blank=Trueのみや、null=Trueのみでは別のエラーが発生するので、
このままにしました。

Python、pip、Djangoをアップデート

pythonを3.8.5にして試しましたが、
変わらずエラーが発生しました。

次に、pipを20.2.2に、Djangoを3.1にアップデートしました。

結局

データを作り直すというのを避けたかったので、
結局DateTimeFieldで、timezone.nowにしました。

時刻が追加されてしまいますが、
表示側でなんとかします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0