我的一个django模型遇到了一个奇怪的情况。我正在将Django 1.10.3与python 3.5.2。
该模型如下所示(为清楚起见已简化):
class Report(models.Model):
date = models.FieldDate()
def fieldA_default(self):
return MyObject.objects.filter(date=self.date).count()
fieldA = models.IntegerField(default=fieldA_default)
我具有创建模型并添加字段的初始迁移,该迁移由django使用自动生成./manage.py makemigrations
。
我将此代码提交到了git仓库中,并将其部署到了我的生产服务器上,但是实际上并未使用该模型(Report
我的数据库中没有对象)。我只是发现此代码不正确(django将模型字段的默认值设置为self属性),并决定改写它save()
。
但是,当我从更改默认的fieldA_default
到0
,运行./manage.py makemigrations
,因为它试图运行老的缺省值函数失败fieldA_default
。在尝试了几个选项之后,我最终决定完全删除该模型。但这也不起作用,因为makemigrations
仍在尝试运行相同的功能。
这是makemigrations
我简单删除模型时的回溯:
Traceback (most recent call last):
File "./manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "venv/lib/python3.5/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
utility.execute()
File "venv/lib/python3.5/site-packages/django/core/management/__init__.py", line 359, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "venv/lib/python3.5/site-packages/django/core/management/base.py", line 294, in run_from_argv
self.execute(*args, **cmd_options)
File "venv/lib/python3.5/site-packages/django/core/management/base.py", line 345, in execute
output = self.handle(*args, **options)
File "venv/lib/python3.5/site-packages/django/core/management/commands/makemigrations.py", line 95, in handle
loader = MigrationLoader(None, ignore_no_migrations=True)
File "venv/lib/python3.5/site-packages/django/db/migrations/loader.py", line 52, in __init__
self.build_graph()
File "venv/lib/python3.5/site-packages/django/db/migrations/loader.py", line 197, in build_graph
self.load_disk()
File "venv/lib/python3.5/site-packages/django/db/migrations/loader.py", line 108, in load_disk
migration_module = import_module("%s.%s" % (module_name, migration_name))
File "venv/lib/python3.5/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 986, in _gcd_import
File "<frozen importlib._bootstrap>", line 969, in _find_and_load
File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 665, in exec_module
File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
File "xxx/reporting/migrations/0001_initial.py", line 9, in <module>
class Migration(migrations.Migration):
File "xxx/reporting/migrations/0001_initial.py", line 22, in Migration
('fieldA', models.IntegerField(default=reporting.models.Report.fieldA_default)),
AttributeError: module 'reporting.models' has no attribute 'Report'
我有几个问题:
即使我要删除模型,Django为什么也要运行此“旧”代码?
因为该模型及其方法仍在迁移文件中引用 0001_initial.py
但是,当我将默认值从fieldA_default更改为0时,运行./manage.py makemigrations失败,因为它试图运行旧的默认值函数fieldA_default。
我假设,在重置字段的默认值之后,您删除了-现在过时的方法fieldA_default
。如上所述,此方法在最初的迁移中已被引用,现在势必会中断。
在没有Django尖叫的情况下,我如何设法将这些无效代码移植到迁移中?
创建迁移后,代码不是无效的。简单向前迁移无法处理模型上的某些更改。在您的情况下:
在引用模型并将其导入迁移文件时删除模型(该文件本身只是另一个python模块,不能仅导入不存在的类)
与删除默认方法相同。
当您的模型代码与您的Migrations / db混乱或不同步并且makemigrations
无法在当前状态下工作时,您可以做的一件事是:
python manage.py migrate app_name zero # undo all existing migrations of app
从应用程序中删除所有迁移文件。或者,如果您已经在数据库中保存了有价值的数据,则可以一一撤消它们,然后查看步骤3是否已经有效。
python manage.py makemigrations app_name # new start from clean sheet
这在开发过程中很容易,并且可以被认为是替代迁移压缩的方法,但是如果您已经在数据库中拥有生产数据,那么显然是最后的选择。但是在那种情况下,无论如何,应该谨慎应用模型更改:)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句