【问题标题】:Django migrate model with user in a foreignkey fails带有外键用户的 Django 迁移模型失败
【发布时间】:2013-09-03 21:05:46
【问题描述】:

我正在尝试迁移我的 django 模型:

from django.contrib.auth.models import User


class Post(models.Model):
    headline = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200)
    body = models.TextField(blank=True, null=True)
    author = models.ForeignKey(User, null=True, blank=True)

我在创建模型后添加了作者字段。

这是 django 创建的迁移:

# encoding: utf8
from django.db import models, migrations


class Migration(migrations.Migration):

    dependencies = [('articles', '0002_auto')]

    operations = [
        migrations.AddField(
            field = models.ForeignKey(to_field=u'id', to=u'auth.User', blank=True, null=True),
            name = 'author',
            model_name = 'post',
        ),
    ]

这是我尝试运行 ./manage.py migrate 时的回溯:

Operations to perform:
  Synchronize unmigrated apps: ckeditor, sessions, admin, messages, auth, staticfiles, contenttypes, django_extensions
  Apply all migrations: articles
Synchronizing apps without migrations:
  Creating tables...
  Installing custom SQL...
  Installing indexes...
Installed 0 object(s) from 0 fixture(s)
Running migrations:
  Applying articles.0002_post_author...Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/USER/.virtualenvs/PROJECT/src/django-trunk/django/core/management/__init__.py", line 397, in execute_from_command_line
    utility.execute()
  File "/home/USER/.virtualenvs/PROJECT/src/django-trunk/django/core/management/__init__.py", line 390, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/USER/.virtualenvs/PROJECT/src/django-trunk/django/core/management/base.py", line 242, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/home/USER/.virtualenvs/PROJECT/src/django-trunk/django/core/management/base.py", line 289, in execute
    output = self.handle(*args, **options)
  File "/home/USER/.virtualenvs/PROJECT/src/django-trunk/django/core/management/commands/migrate.py", line 116, in handle
    executor.migrate(targets, plan, fake=options.get("fake", False))
  File "/home/USER/.virtualenvs/PROJECT/src/django-trunk/django/db/migrations/executor.py", line 60, in migrate
    self.apply_migration(migration, fake=fake)
  File "/home/USER/.virtualenvs/PROJECT/src/django-trunk/django/db/migrations/executor.py", line 73, in apply_migration
    migration.apply(project_state, schema_editor)
  File "/home/USER/.virtualenvs/PROJECT/src/django-trunk/django/db/migrations/migration.py", line 80, in apply
    operation.database_forwards(self.app_label, schema_editor, project_state, new_state)
  File "/home/USER/.virtualenvs/PROJECT/src/django-trunk/django/db/migrations/operations/fields.py", line 22, in database_forwards
    schema_editor.add_field(from_model, to_model._meta.get_field_by_name(self.name)[0])
  File "/home/USER/.virtualenvs/PROJECT/src/django-trunk/django/db/backends/schema.py", line 349, in add_field
    definition, params = self.column_sql(model, field, include_default=True)
  File "/home/USER/.virtualenvs/PROJECT/src/django-trunk/django/db/backends/schema.py", line 105, in column_sql
    db_params = field.db_parameters(connection=self.connection)
  File "/home/USER/.virtualenvs/PROJECT/src/django-trunk/django/db/models/fields/related.py", line 1285, in db_parameters
    return {"type": self.db_type(connection), "check": []}
  File "/home/USER/.virtualenvs/PROJECT/src/django-trunk/django/db/models/fields/related.py", line 1276, in db_type
    rel_field = self.related_field
  File "/home/USER/.virtualenvs/PROJECT/src/django-trunk/django/db/models/fields/related.py", line 1183, in related_field
    return self.foreign_related_fields[0]
  File "/home/USER/.virtualenvs/PROJECT/src/django-trunk/django/db/models/fields/related.py", line 971, in foreign_related_fields
    return tuple(rhs_field for lhs_field, rhs_field in self.related_fields)
  File "/home/USER/.virtualenvs/PROJECT/src/django-trunk/django/db/models/fields/related.py", line 958, in related_fields
    self._related_fields = self.resolve_related_fields()
  File "/home/USER/.virtualenvs/PROJECT/src/django-trunk/django/db/models/fields/related.py", line 943, in resolve_related_fields
    raise ValueError('Related model %r cannot been resolved' % self.rel.to)
ValueError: Related model u'auth.User' cannot been resolved

有人知道我做错了什么吗?

【问题讨论】:

  • 你有没有运气解决这个问题?
  • 以上代码来自 Django 1.7 Alpha。我发现坚持使用 Django 1.6.1 和 South 比使用 Django 1.7 alpha 中的内置迁移更容易。

标签: django migration django-users


【解决方案1】:

在这种情况下对我有什么帮助:

  1. 删除除__init__.py(/%prjname%/migrations 文件夹)以外的所有迁移文件
  2. python manage.py makemigrations
  3. python manage.py migrate

不确定确切原因,但我尝试使用由我的代码合作伙伴生成的文件,但没有成功。

【讨论】:

    【解决方案2】:

    好的,这是 Django 的另一个时髦特性,我花了好几个小时才弄明白。根据https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#substituting-a-custom-user-model

    由于 Django 对可交换模型的动态依赖特性的限制,您必须确保 AUTH_USER_MODEL 引用的模型是在其应用程序的首次迁移中创建的(通常称为0001_initial);否则,您将遇到依赖问题。

    所以要解决这个问题,最好的“干净”方法是将您的自定义用户模型创建放在 0001_initial.py 中,它会简单地工作。这就是 Lebedev Sergey 的 delete/makemigrations 技巧能够奏效的真正原因。

    【讨论】:

    • 也许提供一个小代码示例来说明如何实际完成此操作。否则,恭喜您的第一个答案!
    【解决方案3】:

    如果您在应用任何其他迁移后进行此更改,则需要删除迁移文件夹中的所有其他内容,然后运行“python manage.py makemigrations”。那么你用于 AUTH_USER_MODEL 的任何东西都将是你的第一次迁移。

    【讨论】:

      【解决方案4】:

      如果您不使用自定义用户模型,这可能不是您的问题,但请记住始终使用 get_user_model() 或在引用 User 类时。此外,在定义外键时,settings.AUTH_USER_MODEL 也可以使用,如下所示:

      class MyModel(models.Model):  
          person = models.ForeignKey(settings.AUTH_USER_MODEL)
      

      【讨论】:

        猜你喜欢
        • 2017-04-23
        • 1970-01-01
        • 1970-01-01
        • 2015-05-25
        • 2017-04-09
        • 1970-01-01
        • 2020-05-29
        • 2017-03-10
        相关资源
        最近更新 更多