仅使用电子邮件和密码创建 Django 用户 - UserCreationForm
Creating Django users with just an email and password - UserCreationForm
我需要在我的应用程序中仅使用 email
和 password
字段创建一个用户帐户。因此,我的 models.py 中的自定义用户模型是:
我自定义UserManager来创建用户
from django.contrib.auth.models import BaseUserManager
class UserManager(BaseUserManager):
def _create_user(self, email, password, **extra_fields):
"""
Creates and saves a User with the given email and password.
"""
if not email:
raise ValueError("Users must have an email address")
email = self.normalize_email(email)
user = self.model(email = email, **extra_fields)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', 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)
我的用户模型是:
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from django.utils.translation import ugettext_lazy as _
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True, null=True,
help_text=_('Required. Letters, digits and ''@/./+/-/_ only.'),
validators=[RegexValidator(r'^[\w.@+-]+$', _('Enter a valid email address.'), 'invalid')
])
is_staff = models.BooleanField(
_('staff status'),
default=False,
help_text=_('Designates whether the user can log into this 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.'
),
)
objects = UserManager()
USERNAME_FIELD = "email"
class Meta:
db_table = 'auth_user'
verbose_name_plural = 'Usuarios en la plataforma'
def __str__(self):
return "@{}".format(self.email)
在我的设置中我添加了:
AUTH_USER_MODEL = ‘my_app_name.User’
创建用户 - UserCreationForm
预建 class
要创建用户,我使用 UserCreationForm
class pre-built in the django core.
在此 class 中使用了用户名字段 such as denoted here
根据上述,在我的forms.py中我有:
from django.contrib.auth.forms import UserChangeForm, UserCreationForm
class CustomUserChangeForm(UserChangeForm):
class Meta(UserChangeForm.Meta):
model = get_user_model()
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = get_user_model()
class UserCreateForm(UserCreationForm):
class Meta:
fields = ("email", "password1", "password2",)
model = get_user_model()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["email"].label = "Email address"
当我尝试执行 python manage.py makemigrations 时,我收到此回溯输出错误
bgarcial@elpug ‹ testing ●● › : ~/workspace/ihost_project
[1] % python manage.py makemigrations accounts
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
utility.execute()
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/core/management/__init__.py", line 341, in execute
django.setup()
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/__init__.py", line 27, in setup
apps.populate(settings.INSTALLED_APPS)
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/apps/registry.py", line 115, in populate
app_config.ready()
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/contrib/admin/apps.py", line 23, in ready
self.module.autodiscover()
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/contrib/admin/__init__.py", line 26, in autodiscover
autodiscover_modules('admin', register_to=site)
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/utils/module_loading.py", line 50, in autodiscover_modules
import_module('%s.%s' % (app_config.name, module_to_search))
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 986, in _gcd_import
File "<frozen importlib._bootstrap>", line 969, in _find_and_load
File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 665, in exec_module
File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
File "/home/bgarcial/workspace/ihost_project/accounts/admin.py", line 8, in <module>
from .forms import CustomUserChangeForm, CustomUserCreationForm
File "/home/bgarcial/workspace/ihost_project/accounts/forms.py", line 16, in <module>
class CustomUserCreationForm(UserCreationForm):
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/forms/models.py", line 257, in __new__
raise FieldError(message)
django.core.exceptions.FieldError: Unknown field(s) (username) specified for User
(ihost)
bgarcial@elpug ‹ testing ●● › : ~/workspace/ihost_project
当然,我正在使用 UserCreationForm
django class 核心,我强制使用需要用户名字段的 django 核心功能
如何删除或修改用户名?
我知道不建议修改 django 核心,但是,如何使用 UserCreationForm
django class 核心创建用户而不包含用户名字段?
我尝试在创建用户的地方覆盖我的表单的保存方法,但我没有明确的过程,我认为我不方便的核心是使用 UserCreationForm
django class核心..
class UserCreateForm(UserCreationForm):
class Meta:
fields = ("email", "password1", "password2",)
model = get_user_model()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["email"].label = "Email address"
def save(self, commit=True):
user = super(UserCreateForm, self).save(commit=False)
user.email = self.cleaned_data["email"]
# Tell to Django that not check the username
if commit:
user.save()
return user
如果有人能指出正确的方向,我将不胜感激。 :)
我找到了一个有效的解决方案。
无论如何,请随时提出更好的解决方案!
就像我的 inconvenient/error 与 UserCreationForm
class pre-built in the django core which use the username field in their logic 的使用有关,然后我继续进行以下操作:
在我的forms.py在我的classCustomUserCreationForm
是classUserCreationForm
的child,我override/add 到 Meta
class 属性 fields
,使用 email
字段而不是 username
字段。
This question post 帮我解决一下。
我的classCustomUserCreationForm
保持如下:
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = get_user_model()
fields = ('email',)
然后,我开始执行迁移:
[1] % python manage.py makemigrations accounts
SystemCheckError: System check identified some issues:
ERRORS:
<class 'accounts.admin.UserAdmin'>: (admin.E033) The value of 'ordering[0]' refers to 'username', which is not an attribute of 'accounts.User'.
这个错误告诉我 username
字段不是我的 User
模型的属性。
这意味着 Django 会继续尝试询问用户名字段,即使我用 email
字段覆盖了 fields
值。
当然这是逻辑,因为我仍然继承自UserCreationForm
class pre-built in the django core
然后,我使用 null=True 属性将 username
字段添加到我的用户模型中,这样,在创建用户帐户时不需要用户名:
class User(AbstractBaseUser, PermissionsMixin):
# I had add the username field despite that I don't use in my User model
username = models.CharField(_('username'), max_length=30, null=True,
help_text=_('Required. 30 characters or fewer. Letters, digits and ''@/./+/-/_ only.'),
validators=[RegexValidator(r'^[\w.@+-]+$', _('Enter a valid username.'), 'invalid')
])
email = models.EmailField(unique=True, null=True,
help_text=_('Required. Letters, digits and ''@/./+/-/_ only.'),
validators=[RegexValidator(r'^[\w.@+-]+$', _('Enter a valid email address.'), 'invalid')
])
...
通过这种方式,我执行了迁移
bgarcial@elpug ‹ testing ●● › : ~/workspace/ihost_project
[1] % python manage.py makemigrations accounts
Migrations for 'accounts':
accounts/migrations/0001_initial.py:
- Create model User
(ihost)
bgarcial@elpug ‹ testing ●● › : ~/workspace/ihost_project
python manage.py migrate accounts ...
我的用户名字段仍然保留在我的自定义用户架构中,只是这不是必需的,当我从继承自 UserCreationForm
的 UserCreateForm
class 创建用户时,我可以只用电子邮件和密码创建一个用户帐户
我不知道这是否是解决这一不便的最佳方法。
欢迎提出改进建议!
我需要在我的应用程序中仅使用 email
和 password
字段创建一个用户帐户。因此,我的 models.py 中的自定义用户模型是:
我自定义UserManager来创建用户
from django.contrib.auth.models import BaseUserManager
class UserManager(BaseUserManager):
def _create_user(self, email, password, **extra_fields):
"""
Creates and saves a User with the given email and password.
"""
if not email:
raise ValueError("Users must have an email address")
email = self.normalize_email(email)
user = self.model(email = email, **extra_fields)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', 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)
我的用户模型是:
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from django.utils.translation import ugettext_lazy as _
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True, null=True,
help_text=_('Required. Letters, digits and ''@/./+/-/_ only.'),
validators=[RegexValidator(r'^[\w.@+-]+$', _('Enter a valid email address.'), 'invalid')
])
is_staff = models.BooleanField(
_('staff status'),
default=False,
help_text=_('Designates whether the user can log into this 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.'
),
)
objects = UserManager()
USERNAME_FIELD = "email"
class Meta:
db_table = 'auth_user'
verbose_name_plural = 'Usuarios en la plataforma'
def __str__(self):
return "@{}".format(self.email)
在我的设置中我添加了:
AUTH_USER_MODEL = ‘my_app_name.User’
创建用户 - UserCreationForm
预建 class
要创建用户,我使用 UserCreationForm
class pre-built in the django core.
在此 class 中使用了用户名字段 such as denoted here
根据上述,在我的forms.py中我有:
from django.contrib.auth.forms import UserChangeForm, UserCreationForm
class CustomUserChangeForm(UserChangeForm):
class Meta(UserChangeForm.Meta):
model = get_user_model()
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = get_user_model()
class UserCreateForm(UserCreationForm):
class Meta:
fields = ("email", "password1", "password2",)
model = get_user_model()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["email"].label = "Email address"
当我尝试执行 python manage.py makemigrations 时,我收到此回溯输出错误
bgarcial@elpug ‹ testing ●● › : ~/workspace/ihost_project
[1] % python manage.py makemigrations accounts
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
utility.execute()
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/core/management/__init__.py", line 341, in execute
django.setup()
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/__init__.py", line 27, in setup
apps.populate(settings.INSTALLED_APPS)
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/apps/registry.py", line 115, in populate
app_config.ready()
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/contrib/admin/apps.py", line 23, in ready
self.module.autodiscover()
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/contrib/admin/__init__.py", line 26, in autodiscover
autodiscover_modules('admin', register_to=site)
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/utils/module_loading.py", line 50, in autodiscover_modules
import_module('%s.%s' % (app_config.name, module_to_search))
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 986, in _gcd_import
File "<frozen importlib._bootstrap>", line 969, in _find_and_load
File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 665, in exec_module
File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
File "/home/bgarcial/workspace/ihost_project/accounts/admin.py", line 8, in <module>
from .forms import CustomUserChangeForm, CustomUserCreationForm
File "/home/bgarcial/workspace/ihost_project/accounts/forms.py", line 16, in <module>
class CustomUserCreationForm(UserCreationForm):
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/forms/models.py", line 257, in __new__
raise FieldError(message)
django.core.exceptions.FieldError: Unknown field(s) (username) specified for User
(ihost)
bgarcial@elpug ‹ testing ●● › : ~/workspace/ihost_project
当然,我正在使用 UserCreationForm
django class 核心,我强制使用需要用户名字段的 django 核心功能
如何删除或修改用户名?
我知道不建议修改 django 核心,但是,如何使用 UserCreationForm
django class 核心创建用户而不包含用户名字段?
我尝试在创建用户的地方覆盖我的表单的保存方法,但我没有明确的过程,我认为我不方便的核心是使用 UserCreationForm
django class核心..
class UserCreateForm(UserCreationForm):
class Meta:
fields = ("email", "password1", "password2",)
model = get_user_model()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["email"].label = "Email address"
def save(self, commit=True):
user = super(UserCreateForm, self).save(commit=False)
user.email = self.cleaned_data["email"]
# Tell to Django that not check the username
if commit:
user.save()
return user
如果有人能指出正确的方向,我将不胜感激。 :)
我找到了一个有效的解决方案。
无论如何,请随时提出更好的解决方案!
就像我的 inconvenient/error 与 UserCreationForm
class pre-built in the django core which use the username field in their logic 的使用有关,然后我继续进行以下操作:
在我的forms.py在我的classCustomUserCreationForm
是classUserCreationForm
的child,我override/add 到 Meta
class 属性 fields
,使用 email
字段而不是 username
字段。
This question post 帮我解决一下。
我的classCustomUserCreationForm
保持如下:
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = get_user_model()
fields = ('email',)
然后,我开始执行迁移:
[1] % python manage.py makemigrations accounts
SystemCheckError: System check identified some issues:
ERRORS:
<class 'accounts.admin.UserAdmin'>: (admin.E033) The value of 'ordering[0]' refers to 'username', which is not an attribute of 'accounts.User'.
这个错误告诉我 username
字段不是我的 User
模型的属性。
这意味着 Django 会继续尝试询问用户名字段,即使我用 email
字段覆盖了 fields
值。
当然这是逻辑,因为我仍然继承自UserCreationForm
class pre-built in the django core
然后,我使用 null=True 属性将 username
字段添加到我的用户模型中,这样,在创建用户帐户时不需要用户名:
class User(AbstractBaseUser, PermissionsMixin):
# I had add the username field despite that I don't use in my User model
username = models.CharField(_('username'), max_length=30, null=True,
help_text=_('Required. 30 characters or fewer. Letters, digits and ''@/./+/-/_ only.'),
validators=[RegexValidator(r'^[\w.@+-]+$', _('Enter a valid username.'), 'invalid')
])
email = models.EmailField(unique=True, null=True,
help_text=_('Required. Letters, digits and ''@/./+/-/_ only.'),
validators=[RegexValidator(r'^[\w.@+-]+$', _('Enter a valid email address.'), 'invalid')
])
...
通过这种方式,我执行了迁移
bgarcial@elpug ‹ testing ●● › : ~/workspace/ihost_project
[1] % python manage.py makemigrations accounts
Migrations for 'accounts':
accounts/migrations/0001_initial.py:
- Create model User
(ihost)
bgarcial@elpug ‹ testing ●● › : ~/workspace/ihost_project
python manage.py migrate accounts ...
我的用户名字段仍然保留在我的自定义用户架构中,只是这不是必需的,当我从继承自 UserCreationForm
的 UserCreateForm
class 创建用户时,我可以只用电子邮件和密码创建一个用户帐户
我不知道这是否是解决这一不便的最佳方法。 欢迎提出改进建议!