Opened 6 years ago
Last modified 6 years ago
#29897 closed Bug
Initial migration fails when referencing a custom user model from a sequence of at least two concrete ancestor models — at Initial Version
Reported by: | Steven Ganz | Owned by: | nobody |
---|---|---|---|
Component: | Migrations | Version: | 2.1 |
Severity: | Normal | Keywords: | "custom user model" "abstract model" "foreign key" |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
The following model fails on initial migration.
from django.db import models from django.contrib.auth.models import (AbstractBaseUser) class A(models.Model): createdByUser = models.ForeignKey('User', related_name='creations+', verbose_name='creatorUser', blank=True, null=True, editable=False, on_delete=models.PROTECT) class B(A): pass class User(AbstractBaseUser, B): email = models.EmailField('email address', max_length=256, unique=True, db_index=True) USERNAME_FIELD = 'email' @property def username(self): return self.email
settings.py contains:
AUTH_USER_MODEL = 'core.User'
Applying core.0001_initial...Traceback (most recent call last): File "./manage.py", line 13, in <module> execute_from_command_line(sys.argv) File ".../lib/python3.6/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line utility.execute() File ".../lib/python3.6/site-packages/django/core/management/__init__.py", line 356, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File ".../lib/python3.6/site-packages/django/core/management/base.py", line 283, in run_from_argv self.execute(*args, **cmd_options) File ".../lib/python3.6/site-packages/django/core/management/base.py", line 330, in execute output = self.handle(*args, **options) File ".../lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 204, in handle fake_initial=fake_initial, File ".../lib/python3.6/site-packages/django/db/migrations/executor.py", line 115, in migrate state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial) File ".../lib/python3.6/site-packages/django/db/migrations/executor.py", line 145, in _migrate_all_forwards state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial) File ".../lib/python3.6/site-packages/django/db/migrations/executor.py", line 244, in apply_migration state = migration.apply(state, schema_editor) File ".../lib/python3.6/site-packages/django/db/migrations/migration.py", line 129, in apply operation.database_forwards(self.app_label, schema_editor, old_state, project_state) File ".../lib/python3.6/site-packages/django/db/migrations/operations/fields.py", line 88, in database_forwards field, File ".../lib/python3.6/site-packages/django/db/backends/base/schema.py", line 431, in add_field definition, params = self.column_sql(model, field, include_default=True) File ".../lib/python3.6/site-packages/django/db/backends/base/schema.py", line 160, in column_sql db_params = field.db_parameters(connection=self.connection) File ".../lib/python3.6/site-packages/django/db/models/fields/related.py", line 994, in db_parameters return {"type": self.db_type(connection), "check": self.db_check(connection)} File ".../lib/python3.6/site-packages/django/db/models/fields/related.py", line 991, in db_type return self.target_field.rel_db_type(connection=connection) File ".../lib/python3.6/site-packages/django/db/models/fields/related.py", line 909, in target_field return self.foreign_related_fields[0] File ".../lib/python3.6/site-packages/django/db/models/fields/related.py", line 653, in foreign_related_fields return tuple(rhs_field for lhs_field, rhs_field in self.related_fields if rhs_field) File ".../lib/python3.6/site-packages/django/db/models/fields/related.py", line 640, in related_fields self._related_fields = self.resolve_related_fields() File ".../lib/python3.6/site-packages/django/db/models/fields/related.py", line 625, in resolve_related_fields raise ValueError('Related model %r cannot be resolved' % self.remote_field.model) ValueError: Related model 'core.User' cannot be resolved
Notably, this works fine with any of the following modifications:
- model B is removed, closing the chain
- createdByUser is moved to B or removed altogether
- either A or B is made abstract
- the referenced model is not the custom user model
This is not just a matter of preference for concrete classes, as only a concrete class can be referenced through a foreign key.
Note:
See TracTickets
for help on using tickets.