【问题标题】:'ManyToManyField' object has no attribute 'm2m_reverse_field_name'“ManyToManyField”对象没有属性“m2m_reverse_field_name”
【发布时间】:2016-04-14 10:08:37
【问题描述】:

我正在尝试为我的 Django 项目运行迁移,但出现错误:

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

当我在所有应用程序上运行 make migrations 时,我没有收到任何错误。只有当我尝试实际迁移时。我无法从回溯信息中分辨出哪个模型造成了问题,甚至无法分辨出哪个应用程序。我查看了我的模型,但没有看到任何突然出现的东西。

这是堆栈跟踪:

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'

如何找出问题所在?我应该寻找什么?

【问题讨论】:

  • 您在更改某些模型后出现此错误?
  • 我做了一些小改动。我实际上试图回去并将它们更改为原来的样子,但这似乎并没有什么不同。我没有做任何花哨的事情,实际上只是带有相关名称的多对多字段。
  • 你能显示完整的字段定义吗?
  • 我认为发生的事情是我有两个模型,它们都具有指向对方的多字段。所以 Note 模型有一个 related_cases manytomany 字段指向 Case 模型,而 Case 模型有一个 related_notes 字段指向 Note 模型。我删除了许多字段之一,删除了迁移文件,重新运行 makemigrations,然后运行 ​​migrate 没有错误。

标签: django django-models django-orm


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我的问题是将字段从选择字段更改为多字段。

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

    我关注了丹尼斯·德雷舍:

    基本上检查你的迁移文件并检查 django 对这些字段做了什么。

    如果 django 正在执行 migrations.AlterField 字段,该字段是一个选择字段,现在是一个 manytomanyfield,将其更改为 migrations.RemoveField 然后是 Migrations.AddField

    【讨论】:

      【解决方案3】:

      您必须确保您正在创建“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(...)
      
          ]
      

      【讨论】:

        【解决方案4】:

        我也遇到了同样的问题,但是我修复它的方法是以下步骤: 注意:您将丢失该 ManyToManyField 中的数据

        python manage.py makemigrations app_name
        python manage.py migrate app_name --fake
        

        不要忘记 --fake

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

        在这一步你已经从你的数据库中清除了这个列,你现在需要做的是重新添加 ManyToManyField,所以当你再次 makemigrations app_name & migrate app_name 时。 你的服务器可以完美运行

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

        【讨论】:

          【解决方案5】:

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

          之前:

          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'),
              ),
          ]
          

          虽然更改因神秘原因而失败,但删除并重新创建字段是有效的。

          【讨论】:

          • 那不会删除所有可能存储在这些字段中的数据吗?
          • @Brachamul,是的。这就是我所说的“幸好我的系统中没有任何重要数据,所以我只是将迁移更改如下。”我将进行编辑并使其更清晰。
          • @Sagar 和 jsep 的以下回答更有用
          • @TauPan 已投票。我很怀疑在我的情况下这是一个依赖问题,但时间太长了无法确定。
          【解决方案6】:

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

          【讨论】:

            【解决方案7】:

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

            【讨论】:

            • 这就是导致并为我解决它的原因。我将依赖项添加到迁移中,如下所示:dependencies = [ ..., ('api', '__first__'), ]。之后,AlterField 起作用了。
            • @Brachamul 也许你应该接受这个答案,那么?
            • 我不是问这个问题的人,所以我不能接受答案?
            猜你喜欢
            • 2015-11-10
            • 1970-01-01
            • 2017-04-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-12-01
            • 2021-08-03
            相关资源
            最近更新 更多