【问题标题】:Getting a django.db.utils.OperationalError: no such table With a Custom User Model获取 django.db.utils.OperationalError: no such table With a Custom User Model
【发布时间】:2018-02-15 06:48:10
【问题描述】:

好吧,我在一个名为 accounts 的应用中有一个自定义用户模型。 accounts.User 看起来像这样:

from django.contrib.auth.models import AbstractBaseUser
from django.core.validators import RegexValidator
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver

from accounts.managers import UserManager
from base.models import Model
from accounts.models.profiles import Profile


class User(Model, AbstractBaseUser):
    objects = UserManager()

    phone_regex = RegexValidator(
        regex=r'^\+?1?\d{9,15}$',
        message="Phone number must be entered in the format: '+999999999'. 9-15 digits allowed.",
    )
    phone = models.CharField(
        validators=[phone_regex],
        max_length=17,
        blank=True
    )
    email = models.EmailField(
        max_length=255,
        unique=True,
    )
    active = models.BooleanField(
        default=True
    )
    staff = models.BooleanField(
        default=False
    )
    superuser = models.BooleanField(
        default=False
    )

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    def __str__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        return True

    def has_module_perms(self, app_label):
        return True

    @property
    def is_active(self):
        return self.active

    @property
    def is_staff(self):
        return self.staff

    @property
    def is_superuser(self):
        return self.superuser

    def serialize(self):
        data = {
            'id': self.id,
            'email': self.email,
        }
        return data


@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)


@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
    instance.profile.save()

UserManager 看起来像这样:

from django.contrib.auth.models import BaseUserManager


class UserManager(BaseUserManager):

    def create_user(self, email, password):

        if not email:
            raise ValueError('Users must have an email')

        if not password:
            raise ValueError('Users must have a password')

        user = self.model(
            email=self.normalize_email(email),
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_staffuser(self, email, password):

        user = self.create_user(
            email=email,
            password=password,
        )
        user.staff = True
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password):

        user = self.create_user(
            email=email,
            password=password,
        )
        user.staff = True
        user.superuser = True
        user.save(using=self._db)
        return user

我的帐户应用程序是这样注册的:

...

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

AUTH_USER_MODEL = 'accounts.User'

...

我运行python manage.py makemigrationspython manage.py migrate,一切都按预期运行。当我开始python manage.py createsuperuser 时,问题就发生了。它提示按预期提供电子邮件输入,但是当输入电子邮件并单击输入时,它会返回一个错误。

Traceback(最近一次调用最后一次):

File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute
        return self.cursor.execute(sql, params)
      File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 303, in execute
        return Database.Cursor.execute(self, query, params)
    sqlite3.OperationalError: no such table: accounts_user

上述异常是以下异常的直接原因:

Traceback(最近一次调用最后一次):

File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
    utility.execute()
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/core/management/__init__.py", line 365, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 59, in execute
    return super().execute(*args, **options)
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/core/management/base.py", line 335, in execute
    output = self.handle(*args, **options)
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 117, in handle
    self.UserModel._default_manager.db_manager(database).get_by_natural_key(username)
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/contrib/auth/base_user.py", line 44, in get_by_natural_key
    return self.get(**{self.model.USERNAME_FIELD: username})
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/db/models/query.py", line 397, in get
    num = len(clone)
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/db/models/query.py", line 254, in __len__
    self._fetch_all()
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/db/models/query.py", line 1179, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/db/models/query.py", line 54, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1064, in execute_sql
    cursor.execute(sql, params)
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/db/backends/utils.py", line 100, in execute
    return super().execute(sql, params)
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/db/backends/utils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/db/utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "/Users/zulwiyozaputra/Developer/Environments/poros/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 303, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such table: accounts_user

我正在尝试通过删除数据库并进行迁移来重现错误,但我发现我的应用程序中没有按预期创建迁移文件,因为它应该有我自定义的迁移文件在数据库中创建的用户。以前有人遇到过这个错误吗?你是怎么解决的?

【问题讨论】:

  • 删除您的帐户应用程序内迁移文件夹中的所有文件,init.py 除外。然后尝试再次运行迁移。之后使用 sqlitebrowser 打开创建的数据库文件,查看是否创建了用户表。

标签: python django database sqlite


【解决方案1】:

通过在我的应用程序中手动重新创建 migrations/ 文件夹解决了这个问题。当我删除数据库和迁移文件时,该文件夹被删除。该文件夹不会使用python manage.py makemigrationspython manage.py migrate 自动重新创建。

【讨论】:

    【解决方案2】:

    AbstractBaseUser 创建自定义用户模型时,您不需要将模型类添加为父类,只需留下AbstractBaseUser

    class User(AbstractBaseUser)
    

    清除迁移文件后,重新运行makemigrationsmigrate

    【讨论】:

      【解决方案3】:

      我在使用 AbstractUser 时遇到了同样的问题。创建这些菜单字段。然后添加到用户

      id
      password
      last_login
      is_superuser
      username
      email
      first_name
      last_name
      is_staff
      is_active
      date_joined
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-26
        • 1970-01-01
        • 2019-07-04
        • 1970-01-01
        • 2021-08-03
        • 1970-01-01
        • 2020-11-07
        • 1970-01-01
        相关资源
        最近更新 更多