'ManyToManyField'对象没有属性'm2m_reverse_field_name'

时间:2016-01-09 20:57:26

标签: django django-models django-orm

我正在尝试为我的Django项目运行迁移,但是我收到了错误:

AttributeError: 'ManyToManyField' object has no attribute 'm2m_reverse_field_name'

当我在所有应用上运行迁移时,我没有收到任何错误。只有当我尝试实际迁移时才会这样。我无法从追溯信息中了解哪个模型正在创建问题,甚至是哪个应用程序。我看了我的模特,我没有看到任何突然出现的东西。

这是堆栈跟踪:

Operations to perform:
  Apply all migrations: admin, sessions, case_manager, file_manager, auth, contenttypes, tasks, people_and_property
Running migrations:
  Rendering model states... DONE
  Applying file_manager.0006_auto_20160109_1536...Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/mint/Python_Projects/venv/lib/python3.4/site-packages/django/core/management/__init__.py", line 350, in execute_from_command_line
    utility.execute()
  File "/home/mint/Python_Projects/venv/lib/python3.4/site-packages/django/core/management/__init__.py", line 342, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/mint/Python_Projects/venv/lib/python3.4/site-packages/django/core/management/base.py", line 348, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/mint/Python_Projects/venv/lib/python3.4/site-packages/django/core/management/base.py", line 399, in execute
    output = self.handle(*args, **options)
  File "/home/mint/Python_Projects/venv/lib/python3.4/site-packages/django/core/management/commands/migrate.py", line 200, in handle
    executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
  File "/home/mint/Python_Projects/venv/lib/python3.4/site-packages/django/db/migrations/executor.py", line 92, in migrate
    self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "/home/mint/Python_Projects/venv/lib/python3.4/site-packages/django/db/migrations/executor.py", line 121, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "/home/mint/Python_Projects/venv/lib/python3.4/site-packages/django/db/migrations/executor.py", line 198, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/home/mint/Python_Projects/venv/lib/python3.4/site-packages/django/db/migrations/migration.py", line 123, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "/home/mint/Python_Projects/venv/lib/python3.4/site-packages/django/db/migrations/operations/fields.py", line 201, in database_forwards
    schema_editor.alter_field(from_model, from_field, to_field)
  File "/home/mint/Python_Projects/venv/lib/python3.4/site-packages/django/db/backends/base/schema.py", line 467, in alter_field
    return self._alter_many_to_many(model, old_field, new_field, strict)
  File "/home/mint/Python_Projects/venv/lib/python3.4/site-packages/django/db/backends/sqlite3/schema.py", line 274, in _alter_many_to_many
    old_field.remote_field.through._meta.get_field(old_field.m2m_reverse_field_name()),
AttributeError: 'ManyToManyField' object has no attribute 'm2m_reverse_field_name'

如何确定哪个型号是问题?我应该寻找什么?

7 个答案:

答案 0 :(得分:8)

您必须确保已在数据库中创建了创建“ManyToManyField”的模型。

您可以通过将创建模型的迁移作为依赖项添加到您更改字段的迁移中来实现:

场景1:您使用其他应用中的模型将字段更改为“ManyToManyField”

class Migration(migrations.Migration):

    dependencies = [
      ..........
      ('[app]', '__first__'),
    ]

    operations = [
       .........
    ]

场景2:您创建了一个'ManyToManyField',而您所引用的模型位于同一个文件中:

 class Migration(migrations.Migration):

    dependencies = [
      ..........
    ]

    operations = [
       .........
       # Make sure the model you are making the reference with is  before the ManyToManyField
       migrations.CreateModel(...) ,
       migrations.AlterField/CreateField(...)

    ]

答案 1 :(得分:4)

我遇到了同样的问题,但我不知道是否出于同样的原因。幸运的是,我在系统中没有任何重要数据,因此我只是按照以下方式更改了迁移 - 但请注意,这会删除这些列中的所有数据!

在:

operations = [
    migrations.AlterField(
        model_name='resource',
        name='authors',
        field=models.ManyToManyField(related_name='resources_authored', to='api.Person'),
    ),
    migrations.AlterField(
        model_name='resource',
        name='editors',
        field=models.ManyToManyField(blank=True, related_name='resources_edited', to='api.Person'),
    ),
]

后:

operations = [
    migrations.RemoveField(
        model_name='resource',
        name='authors',
    ),
    migrations.RemoveField(
        model_name='resource',
        name='editors',
    ),
    migrations.AddField(
        model_name='resource',
        name='authors',
        field=models.ManyToManyField(related_name='resources_authored', to='api.Person'),
    ),
    migrations.AddField(
        model_name='resource',
        name='editors',
        field=models.ManyToManyField(blank=True, related_name='resources_edited', to='api.Person'),
    ),
]

虽然因为神秘的原因而改变了,但删除并重新创建了这些字段。

答案 2 :(得分:2)

其中一个原因可能是您的api.Person模型迁移可能没有在引用它之前运行(在您的示例中为file_manager.0006_auto_20160109_1536)。因此,请先确保api.Person迁移是通过在file_manager.0006_auto_20160109_1536的依赖项中添加它们来运行的。

答案 3 :(得分:0)

当我尝试重命名一个用多对多字段引用的表时,我遇到了同样的问题。 我这样解决了: - 将manytomany关系数据转储到文件中 - 删除了manytomany字段并进行了迁移 - 重命名表并迁移 - 添加了manytomany字段并迁移并加载了转储中的关系

答案 4 :(得分:0)

我也有同样的问题,但我修复它的方法是以下步骤: 注意:您将丢失ManyToManyField

中的数据
python manage.py makemigrations app_name
python manage.py migrate app_name --fake

不要忘记--fake

之后。 我删除了(或只是注释该行)ManyToMany字段,然后makemigrations app_name,迁移app_name。

在此步骤中,您清除了数据库中的此列,您现在需要做的是重新添加ManyToManyField,因此当您创建数字时app_name&amp;再次迁移app_name。 您的服务器可以完美运行

这不是最好的,但它对我有用。 希望它会有所帮助!

答案 5 :(得分:0)

我的问题来自将字段从选择字段更改为多方字段。

如果您这样做并保持相同的名称,则会遇到问题。

我关注了Denis Drescher:

基本上检查您的迁移文件,并检查django对这些字段的作用。

如果django正在进行migrations.AlterField作为选择字段的字段,现在是manytomanyfield,请将其更改为 migrations.RemoveField,然后是Migrations.AddField

答案 6 :(得分:0)

我还没有有意义的数据,所以我删除了数据库(db.sqlite3)和所有迁移(0001,0002 等)