扩展我的 Django 用户模型的问题

Posted

技术标签:

【中文标题】扩展我的 Django 用户模型的问题【英文标题】:Problems extending my Django user model 【发布时间】:2017-08-25 04:29:03 【问题描述】:

我有一个简单的 django 应用程序,并且正在尝试设置一个自定义 Django 用户模型,以便我可以让用户使用他们的电子邮件字段登录。我认为我将所有内容都设置得很好,一切都相当简单,但是在尝试实际运行迁移时出现此错误:

django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency accounts.0001_initial

看起来很奇怪?

我无法理解为什么无法理解。

这是我正在实现的用户模型

from __future__ import unicode_literals

from django.db import models
from django.core.mail import send_mail
from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.base_user import AbstractBaseUser
from django.utils.translation import ugettext_lazy as _

from .managers import UserManager


class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(_('email address'), unique=True)
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=30, blank=True)
    display_name = models.CharField(_('display name'), max_length=30, blank=True)
    bio = models.TextField(blank=True)
    date_joined = models.DateTimeField(_('date joined'), auto_now_add=True)
    is_active = models.BooleanField(_('active'), default=True)
    avatar = models.ImageField(upload_to='avatars/', null=True, blank=True)

objects = UserManager()

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []

class Meta:
    verbose_name = _('user')
    verbose_name_plural = _('users')

def get_full_name(self):
    '''
    Returns the first_name plus the last_name, with a space in between.
    '''
    full_name = '%s %s' % (self.first_name, self.last_name)
    return full_name.strip()

def get_short_name(self):
    '''
    Returns the short name for the user.
    '''
    return self.first_name

def email_user(self, subject, message, from_email=None, **kwargs):
    '''
    Sends an email to this User.
    '''
    send_mail(subject, message, from_email, [self.email], **kwargs)

【问题讨论】:

【参考方案1】:

“启动项目时使用自定义用户模型”

如果您要开始一个新项目,强烈建议您设置自定义用户模型,即使默认用户模型对您来说已经足够了。此模型的行为与默认用户模型相同,但您可以在未来需要时对其进行自定义。”reference->django docs

然后你必须在 setting.py 中指定你正在使用一个新的用户模型(同样在你第一次迁移之前。)

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    pass

# in settings.py

AUTH_USER_MODEL = 'myapp.MyUser'

我强烈建议您查看上面的链接。

现在要解决您的问题,您可以在迁移目录下的应用路径中删除您的迁移,然后重置您的数据库并按照上述说明进行操作。

在 django 中更改用户模型中间项目很困难,并且需要手动编辑您的架构,因此由于您的项目用于教育目的,只需重置它

【讨论】:

重置数据库是指删除整个数据库吗?【参考方案2】:

基本上,您已经创建了一些用户帐户或至少创建了超级用户帐户。由于您在我假设您已经进行了至少一次迁移之后更改了用户模型,因此 Django 与旧用户模型与新用户模型发生冲突。

解决方案是删除管理员中的所有帐户,包括超级用户。然后删除迁移文件夹中的迁移文件。而且我认为删除你的 sqlite 数据文件。再次运行迁移,它应该可以工作。

您应该在任何迁移之前创建自定义用户模型。

【讨论】:

第一个django项目,以后会记住的。【参考方案3】:

一种解决方案是截断django_migrations 表。

为此,您必须:

使用mysql -u root -p登录到您的数据库(如果您使用Mysql)

use your_db_name;

SET FOREIGN_KEY_CHECKS=0; 防止关系错误

DELETE FROM django_migrations; 截断django_migrations

SET FOREIGN_KEY_CHECKS=1;

然后你就可以运行你的迁移了!

另一种解决方案是在迁移之前运行这些命令以避免迁移错误:

python manage.py migrate admin zero --fake
python manage.py migrate auth zero --fake
python manage.py migrate contenttypes zero --fake
python manage.py migrate sessions zero --fake

警告:

此解决方案可能会给您留下一个数据库架构,即 与应用的迁移不一致,因此仅在以下情况下执行此操作 你知道你在做什么。感谢@AKX

你也可以使用this解决方案!

【讨论】:

此解决方案可能会给您留下与应用的迁移不一致的数据库架构,因此只有在您知道自己在做什么的情况下才这样做。

以上是关于扩展我的 Django 用户模型的问题的主要内容,如果未能解决你的问题,请参考以下文章

django 1.5 扩展默认用户模型或替换它

Django:扩展用户模型避免数据库连接

如何正确扩展 django 用户模型

在 Django 中扩展用户对象:用户模型继承还是使用 UserProfile?

在 Django 中使用更多字段扩展用户模型的最佳方法是啥?

如何扩展 Django 用户模型来管理权限