我正在尝试自定义用户模型(名称:UserProfile),但是当我进行 makemigrations 时出现错误:
AttributeError: Manager isn't available; 'auth.User' has been swapped for 'accounts.UserProfile'
所以我遵循(经理不可用;用户已被交换为 'pet.Person')的建议并进行了一些更改。我放
from django.contrib.auth import get_user_model
User = get_user_model()
在自定义用户模型导入的每个文件(设置、序列化程序、模型、表单、管理员)中,但这次我收到了另一条错误消息:
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
我该如何解决这个问题?
以下是文件:
设置.py
> import os import datetime from django.conf import settings
>
>
> # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR =
> os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
>
>
> # Quick-start development settings - unsuitable for production
> # See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
>
> # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'ruho^096p16m=vg!sn(&o46-qwe#y(zf^bee&!wujo-4h@%hgl'
>
> # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True
>
> ALLOWED_HOSTS = ['*']
>
>
> # Application definition INSTALLED_APPS = [
> 'rest_framework', # Django rest framework 套件
> 'rest_framework.authtoken',
> 'grappelli', # grappelli admin 版面套件
> 'django.contrib.admin',
> 'django.contrib.auth',
> 'django.contrib.contenttypes',
> 'django.contrib.sessions',
> 'django.contrib.messages',
> 'django.contrib.staticfiles',
> 'django.contrib.sites',
> 'rest_auth',
> 'rest_auth.registration',
> 'debug_toolbar', # django debug 工具列
> 'django_extensions', # django 擴展套件,提供一些cli指令
> 'import_export', # 可從 admin 匯出資料 (目前因版本關係,所以無法使用)
> 'django_filters', # 優化從model query 資料效能
> 'allauth', # django allauth 套件
> 'allauth.account', # django allauth 套件
> 'allauth.socialaccount', # django allauth 套件
> 'allauth.socialaccount.providers.facebook', # django allauth 套件,設定使用FB登入用
> # 'rest_framework_docs', # 可輸出API文件 (目前因版本關係,所以無法使用)
> 'books', # 書籍APP
> 'accounts',# 使用者帳號APP ]
>
> from django.contrib.auth import get_user_model
User = get_user_model()
>
> AUTH_USER_MODEL = 'accounts.UserProfile'
>
> MIDDLEWARE = [
> 'django.middleware.security.SecurityMiddleware',
> 'django.contrib.sessions.middleware.SessionMiddleware',
> 'django.middleware.common.CommonMiddleware',
> 'django.middleware.csrf.CsrfViewMiddleware',
> 'django.contrib.auth.middleware.AuthenticationMiddleware',
> 'django.contrib.messages.middleware.MessageMiddleware',
> 'django.middleware.clickjacking.XFrameOptionsMiddleware',
> 'debug_toolbar.middleware.DebugToolbarMiddleware', ]
>
> INTERNAL_IPS = ('127.0.0.1',)
>
> # 配置django_rest_framework REST_FRAMEWORK = {
> # Use Django's standard `django.contrib.auth` permissions,
> # or allow read-only access for unauthenticated users.
> 'DEFAULT_AUTHENTICATION_CLASSES': (
> 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
> 'rest_framework.authentication.SessionAuthentication',
> 'rest_framework.authentication.BasicAuthentication',
> ),
> 'DEFAULT_PERMISSION_CLASSES': [
> 'rest_framework.permissions.IsAuthenticated',
> ] }
>
> # 配置JQuery和SHOW_TOOLBAR_CALLBACK DEBUG_TOOLBAR_CONFIG = {
> 'JQUERY_URL': 'https://ajax.googleapis.com/ajax/libs/dojo/1.13.0/dojo/dojo.js',
> 'SHOW_TOOLBAR_CALLBACK': lambda request: DEBUG, }
....
模型.py
from django.db import models
from django.conf import settings
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from books.models import Bookinfo
from datetime import datetime, timedelta
import jwt
from django.contrib.auth import get_user_model
User = get_user_model()
# 建立usermanager定義使用者和高級使用者instance作為數據查詢的管理器
class UserManager(BaseUserManager):
# 建立一般使用者
def create_user(self, username, email, password=None):
# 判斷使用者是否有輸入使用者名稱和email
if username is None:
raise TypeError('請填入使用者名稱')
if email is None:
raise TypeError('請填入Email')
user = self.model(
username=username,
email=self.normalize_email(email)
)
user.set_password(password)
user.save()
return user
# 建立高級使用者
def create_superuser(self, username, email, password):
if password is None:
raise TypeError('Superusers must have a password')
# 直接使用建立一般使用者方法
user = self.create_user(username, email, password)
user.is_superuser = True
user.is_staff = True
user.save()
return user
# 定義使用者資料表
class UserProfile(AbstractBaseUser, PermissionsMixin):
class Meta:
db_table = 'userprofile'
# 定義使用者需填入資料
username = models.CharField(max_length=255, db_index=True, unique=True, verbose_name='用戶名')
user_image = models.ImageField(upload_to='img', verbose_name='用戶圖片')
email = models.EmailField(db_index=True, unique=True, verbose_name='電子郵件')
birthday = models.DateField(verbose_name='生日')
GENDER_CHOICES = (
('Male', '男'),
('Female', '女')
)
gender = models.CharField(
max_length=5, choices=GENDER_CHOICES, verbose_name='性別')
location = models.CharField(max_length=255, blank=True, verbose_name='地區')
about = models.TextField(blank=True, verbose_name='關於我')
# 確認使用者是否還有再使用平台
is_active = models.BooleanField(default=True)
# 確認使用者是否為管理者
is_staff = models.BooleanField(default=False)
# 創建時間
create_at = models.DateTimeField(auto_now_add=True)
# 更新資料時間
update_at = models.DateTimeField(auto_now=True)
# 外鍵:將評論和書櫃關聯起來
com = models.OneToOneField(
'Comments', null=True, blank=True, on_delete=models.CASCADE, verbose_name='評論ID')
bookshelf = models.OneToOneField(
'bookshelf', null=True, blank=True, on_delete=models.CASCADE, verbose_name='書櫃ID')
# The `USERNAME_FIELD` property tells us which field we will use to log in.
# In this case we want it to be the email field.
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
# Tells Django that the UserManager class defined above should manage
# objects of this type.
objects = UserManager()
def __str__(self):
"""
Returns a string representation of this `User`.
This string is used when a `User` is printed in the console.
"""
return self.email
@property
def token(self):
"""
Allows us to get a user's token by calling `user.token` instead of
`user.generate_jwt_token().
The `@property` decorator above makes this possible. `token` is called
a "dynamic property".
"""
return self._generate_jwt_token()
def get_full_name(self):
"""
This method is required by Django for things like handling emails.
Typically this would be the user's first and last name. Since we do
not store the user's real name, we return their username instead.
"""
return self.username
def get_short_name(self):
"""
This method is required by Django for things like handling emails.
Typically, this would be the user's first name. Since we do not store
the user's real name, we return their username instead.
"""
return self.username
def _generate_jwt_token(self):
"""
Generates a JSON Web Token that stores this user's ID and has an expiry
date set to 60 days into the future.
"""
dt = datetime.now() + timedelta(days=60)
token = jwt.encode({
'id': self.pk,
'exp': int(dt.strftime('%s'))
}, settings.SECRET_KEY, algorithm='HS256')
return token.decode('utf-8') ....
表格.py
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import UserProfile
from django.contrib.auth import get_user_model
User = get_user_model()
class UserProfileForm(UserCreationForm):
class Meta:
model = UserProfile
fields = (
'username', 'user_image', 'email', 'gender',
'birthday', 'location', 'about'
)
class UserProfileChangeForm(UserChangeForm):
class Meta:
model = UserProfile
fields = UserChangeForm.Meta.fields
管理员.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import Comments, Bookshelf, UserProfile
from import_export.admin import ImportExportModelAdmin
from .forms import UserCreationForm, UserChangeForm
from django.contrib.auth import get_user_model
User = get_user_model()
class UserProfileAdmin(UserAdmin):
add_form = UserCreationForm
form = UserChangeForm
model = UserProfile
list_display = ('_id', 'user_name', 'e-mail', 'gender',
'birthday', 'location', 'created_at')
search_fields = ['user_name', 'gender']
class CommentsAdmin(ImportExportModelAdmin):
list_display = ('_id', 'rating', 'read_status', 'created_time')
search_fields = ['rating']
class BookshelfAdmin(ImportExportModelAdmin):
list_display = ('_id', 'created_time')
# search_fields = ['gender']
admin.site.register(UserProfile, UserProfileAdmin)
admin.site.register(Comments, CommentsAdmin)
admin.site.register(Bookshelf, BookshelfAdmin)
版本:Django 2.1.1,python 3.6.3