我已经在一个项目上工作了一段时间,并且在迁移方面没有遇到任何问题。 我决定重置数据库和迁移,我时常这样做。 我删除了所有迁移,重新创建它们,然后重新创建数据库后,应用迁移,此时,我收到错误“
Migration users.0001_initial is applied before its dependency auth.0012_alter_user_first_name_max_length on database 'default'.
”
现在,
auth.0012_alter_user_first_name_max_length
显然来自django.contrib.auth
,它是核心django的一部分,所以我不明白为什么我需要在新项目中依赖它的迁移,但是每当我从首先,它添加了对我的用户模型 auth.0012_alter_user_first_name_max_length
的依赖。 我不知道为什么它会这样做,而昨天它显然没有这样做,但我现在必须在迁移之前手动从用户迁移中删除该依赖项。
可能是什么原因造成的。
这是我的 users.models.py 文件。 也许有人能弄清楚它会这样做有什么奇怪的。
from django.contrib.auth.models import AbstractUser
from django.db.models import CharField, EmailField
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from phonenumber_field.modelfields import PhoneNumberField
from django.contrib.auth.models import UserManager
from django.db.models import Q
# Override UserManager and allow login with both username and email address
class CustomUserManager(UserManager):
def get_by_natural_key(self, username):
return self.get(
Q(**{self.model.USERNAME_FIELD: username}) |
Q(**{self.model.EMAIL_FIELD: username})
)
class User(AbstractUser):
class Meta(object):
unique_together = ('email',)
email = EmailField(_('email address'), unique=True, blank=True, max_length=255)
phone_number = PhoneNumberField(_('Phone number'), blank=True)
address = CharField(_("Street address"), blank=True, max_length=255)
city = CharField(_("City"), blank=True, max_length=255)
state = CharField(_("State"), blank=True, max_length=255)
zip = CharField(_("ZIP"), blank=True, max_length=255)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['first_name', 'last_name', 'email']
# for allowing both username and email login
objects = CustomUserManager()
def get_absolute_url(self):
"""Get url for user's detail view.
Returns:
str: URL for user detail.
"""
return reverse("users:detail", kwargs={"username": self.username})
这对我有用
设置.py:
INSTALLED_APPS = [
...
#'django.contrib.admin',
...
]
urls.py:
urlpatterns = [
path('profile/', include('restapp.urls')),
#path('admin/', admin.site.urls),
]
迁移您的表:
python manage.py makemigrations
python manage.py migrate
取消注释两个网址和这个:
INSTALLED_APPS = [
...
'django.contrib.admin',
...
]
再次:
python manage.py makemigrations
python manage.py migrate
Django 会在名为
django_migrations
的表中跟踪已运行的迁移。当你运行 migrate
时:
当 django 检测到迁移已经以某种方式运行时,就会引发
InconsistentMigrationHistory
错误,而这本来是不可能的(例如,如果它已经运行,但它的依赖项之一尚未运行)。
我不知道你是如何删除你的数据库的,但显然这个表(
django_migrations
)没有被正确删除,或者自从被擦除以来它已经被篡改了。否则就不会引发此错误。 users.0001_initial
已经被应用,而auth.0012_alter_user_first_name_max_length
还没有应用,这是非常奇怪。我真的不确定这是怎么发生的。您对该表进行过手动编辑吗???
如上所述,半删除数据库会导致比上述错误更大的问题。如果某些迁移没有运行,因为 django 认为它们已经应用,而实际上它们没有应用,那么您的代码和数据库可能会完全不同步。确保您已正确完全擦除数据库(特别是
django_migrations
表)。
不,这可能会给您带来问题。由于
User
继承自 AbstractUser
,因此它将继承 user_permissions
,这是与 auth.Permission
的多对多字段。 (它还将继承一个带有 auth.Group
的多对多字段)。
为了让您的新迁移正常工作,需要首先等待
auth.Permission
(和auth.Group
)正确设置,这样才能正确设置多对多字段。在新迁移运行之前需要先运行 contrib.auth
迁移是依赖于 auth_0012...
的原因。
(它是
contrib.auth
中的最后一次迁移,而不是最后一次涉及 Permission
或 Group
的原因只是 makemigrations
算法的工作方式。它还不够聪明,无法弄清楚要指向哪个迁移,所以它只指向该应用程序中的最后一个。)
我在升级到 django 3.1 时遇到过这个问题。这是添加了
auth.0012
迁移的版本。
我的应用程序的初始迁移具有以下依赖项:
dependencies = [
('contenttypes', '__latest__'),
('auth', '__latest__'),
...
]
由于现在最新的身份验证迁移是
auth.0012
尚未应用,因此应用程序的依赖项未满足并且迁移失败:
django.db.migrations.exceptions.InconsistentMigrationHistory:迁移 dbentry.0001_initial 在数据库“default”上的依赖项 auth.0012_alter_user_first_name_max_length 之前应用
将身份验证依赖项设置为已应用的最新迁移:在我的例子中为
('auth', '0011_update_proxy_permissions')
。然后迁移将运行并应用 auth.0012
。此时,您可以将依赖项设置回 __latest__
- 尽管这可能意味着下次 django.auth 添加迁移时必须重复此过程。
问题出现在django升级到3.1的过程中,该版本添加了auth.0012!要检查本地设置的最新内容,您可以运行
python manage.py showmigrations
它将显示上次应用的迁移,将上次应用的身份验证迁移添加为 inital0001 迁移文件中的依赖项,然后就可以开始了!
对我来说就是这个
('auth', '0006_require_contenttypes_0002'),