Django自定义用户模型:初始迁移取决于默认身份验证应用

时间:2017-02-05 17:51:02

标签: django django-models

我正在开发一个新的Django应用程序,并在创建任何用户或进行任何实际工作之前转移到由名为accounts的应用程序提供的自定义用户模型。这似乎很好 - 我创建了几个用户&自定义管理员,以便我可以编辑&从那里创建用户。

我将我的回购克隆到了另一台计算机&尝试启动开发服务器时遇到错误:

secondary machine after trying to start dev server

这是有道理的,因为我无法在项目目录中找到任何auth次迁移。但是,当我在我的主开发机器上创建一个新数据库&运行./manage.py migrate,输出包含auth应用的8次迁移:

main dev machine after migrating new db

在我的辅助计算机上,我可以在accounts初始迁移中注释掉依赖项,看起来工作正常 - 开发服务器启动,我可以看到从我的主开发机器添加的用户(I&# 39; m现在使用sqlite3 DB,&但是我需要使用Django管理员。

我认为依赖可能在某种程度上是一个遗留物,所以我想我可以删除引用。但是,如果我评论出对我的开发机器和放大器的依赖性。尝试迁移新数据库,我收到一个错误。

我在这里难倒 - 如果我没有实际的迁移文件,这些auth迁移在哪里?它们是django.contrib.auth的内置插件吗?

编辑:看起来内置auth迁移,为什么我的项目在尝试启动第二台计算机上的dev服务器时无法访问它们?我已尝试专门为auth应用程序进行迁移,以确保它们存在,但报告没有任何更改。

作为参考,这是我的accounts型号&管理器:

# accounts/models.py
"""
This model defines the custom user object
The main object of this user model is to use email as the
main unique field and remove username as a required field
"""

from django.contrib import auth
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.contrib.auth.signals import user_logged_in
from django.contrib.contenttypes.models import ContentType
from django.core import validators
from django.core.exceptions import PermissionDenied
from django.core.mail import send_mail
from django.db import models
from django.db.models.manager import EmptyManager
from django.utils import six, timezone
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _

class UserManager(BaseUserManager):
    use_in_migrations = True

    def _create_user(self, email, password, username=None, **extra_fields):
        """
        Creates and saves a User with the given username, email and password.
        """
        if not email:
            raise ValueError('The given email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email, username=None, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(email, password, **extra_fields)

    def create_superuser(self, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self._create_user(email, password, **extra_fields)

class User(AbstractBaseUser, PermissionsMixin):
    """
    A base class implementing a fully featured User model with
    admin-compliant permissions.
    Email and password are required. Other fields are optional.
    """
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=30, blank=True)
    username = models.CharField(
        _('username'),
        max_length=150,
        blank=True,
        null=True,
        help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
        validators=[
            validators.RegexValidator(
                r'^[\w.@+-]+$',
                _('Enter a valid username. This value may contain only '
                  'letters, numbers ' 'and @/./+/-/_ characters.')
            ),
        ],
        error_messages={
            'unique': _("A user with that username already exists."),
        },
    )
    email = models.EmailField(
        _('Email Address'), unique=True,
        error_messages={
            'unique': _("A user with that email already exists."),
        }
    )
    is_staff = models.BooleanField(
        _('staff status'),
        default=False,
        help_text=_('Designates whether the user can log into this admin site.'),
    )
    is_active = models.BooleanField(
        _('active'),
        default=True,
        help_text=_(
            'Designates whether this user should be treated as active. '
            'Unselect this instead of deleting accounts.'
        ),
    )
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

    #app-specific user fields
    has_picked = models.BooleanField(default=False)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

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

    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)

    @property
    def display_name(self):
        """
        Returns first name and last initial, first name, or email prefix
        Depending on whats available
        """
        if self.first_name:
            if self.last_name:
                return self.first_name + ' ' + self.last_name[0] + '.'
            else:
                return self.first_name
        else:
            return self.email.split('@')[0]

我的INSTALLED_APPS:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'accounts',
]

1 个答案:

答案 0 :(得分:1)

在Django 1.10中添加了auth app中的迁移0008。你可能在另一台机器上运行旧版本的Django。