如何解决在 Django 中从标准用户迁移到抽象自定义用户
我使用标准的用户表单创建了一个 Django 项目。我真的需要使用电子邮件作为登录名(使用 this 指南)。问题是当我已经使用了标准的用户表单时,它应该很难迁移。
由于我们目前仅处于测试阶段,因此我不介意擦除整个数据库以进行此迁移。 考虑到这一点,丢失数据不是问题,有没有办法进行这种迁移?
编辑(添加了一些解释):
现在我有“平常”
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm,PasswordChangeForm
class UserRegisterForm(UserCreationForm):
class Meta:
model = User
fields = ["username","email","password1","password2"]
即登录名由用户名和密码组成。假设我想创建自己的用户 (here),我可以理解,因为我的数据库中已经有用户,所以这会很困难。
所以问题是;如果我使用“标准”用户模型来创建用户,并且我想从该模型开始并使用电子邮件作为登录名(而不是用户名),我该怎么做?
解决方法
使用此代码,您将从自定义用户中删除用户名。因此,您可以使用电子邮件而不是用户名登录。
在YOUR_APP/models.py
。
from django.contrib.auth.models import AbstractUser,BaseUserManager,Group
from django.conf import settings
from django.db import models
from django.utils.translation import gettext as _
class UserManager(BaseUserManager):
"""
Model manager for User model without username field
"""
use_in_migrations = True
def create_user(self,email,password,**extra_fields):
"""
Create a User with the given email and password
"""
if not email:
raise ValueError('The 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_superuser(self,**extra_fields):
"""
Create a SuperUser with the given email and password
"""
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,**extra_fields)
class User(AbstractUser):
"""
Store a custom user
"""
username = None
email = models.EmailField(_('email address'),unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
class Meta:
db_table = "auth_user"
def __str__(self):
return self.email
class ProxyUser(User):
class Meta:
app_label = "auth"
proxy = True
verbose_name = "User"
verbose_name_plural = "Users"
class ProxyGroup(Group):
class Meta:
app_label = "auth"
proxy = True
verbose_name = "Group"
verbose_name_plural = "Groups"
在YOUR_APP/forms.py
from django.contrib.auth.forms import UserCreationForm,UserChangeForm
from .models import User
class MyUserCreationForm(UserCreationForm):
"""
Added creation of the user form.
"""
class Meta(UserCreationForm):
model = User
fields = ["email"]
class MyUserChangeForm(UserChangeForm):
"""
Added updating of the user form.
"""
class Meta:
model = User
fields = ["email"]
在 YOUR_APP/Admin.py
中,如果您想使用 Django-Admin
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.utils.translation import gettext as _
from .models import User,ProxyUser,ProxyGroup
from .forms import MyUserCreationForm,MyUserChangeForm
class MyUserAdmin(UserAdmin):
"""
Django admin to Users (customizing authentication user)
"""
add_form = MyUserCreationForm
form = MyUserChangeForm
model = User
list_display = [
"email","first_name","last_name","is_staff"
]
list_display_links = [
"email"
]
search_fields = [
"email","last_name"
]
fieldsets = [
("Access info",{
"fields": ("email","password")
}),("Personal info",{
"fields": ("first_name","last_name")
}),("Permissions",{
"fields": ("is_active","is_staff","is_superuser","groups","user_permissions")
}),("Important dates",{
"fields": ("last_login","date_joined")
}),]
add_fieldsets = [
("Access info",{
"classes": ("wide",),"fields": ("email","password1","password2"),}),]
ordering = [
"email"
]
admin.register(ProxyUser,MyUserAdmin)
admin.register(ProxyGroup)
在 settings.py
中,您需要重定向到自定义用户
AUTH_USER_MODEL = "YOUR_APP.User"
如果您在执行此操作之前已经进行了迁移。 请确保删除/删除并重新创建数据库,并删除您项目的迁移文件夹和 pycache
文件夹以避免问题。
最后,做迁移
python manage.py migrate YOUR_APP
如果迁移有问题,可以试试下面的代码,而不是前面的
python manage.py migrate YOUR_APP
python manage.py migrate auth
python manage.py migrate contenttypes
python manage.py migrate admin
python manage.py migrate sessions
希望对您有所帮助。
,在 Django documentation 中,他们强烈建议在开始新项目时设置自定义用户模型,即使默认的模型对您来说已经足够了。所以要使用电子邮件作为登录,首先你需要添加一个自定义用户模型:
# YourApp/models.py
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
email = models.EmailField('email address',unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
接下来,您需要将 AUTH_USER_MODEL
指向 settings.py
中的自定义用户模型:
# settings.py
AUTH_USER_MODEL = 'YouApp.User'
另外,请确保更新 forms.py
和 admin.py
文件:
# YourApp/forms.py
class YourSignUpForm(UserCreationForm):
class Meta:
model = User
fields = ("username","email","password2")
# YourApp/admin.py
from YourApp.models import User
admin.site.register(User,UserAdmin)
最后,您需要删除数据库并重新创建它。例如,如果您使用的是 postgres,请执行以下操作:
(venv) $ sudo -u postgres psql
postgres=# DROP DATABASE YourDB;
postgres=# CREATE DATABASE YourDB;
并运行迁移:
python manage.py migrate
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。