簡體   English   中英

僅使用電子郵件和密碼創建Django用戶-UserCreationForm

[英]Creating Django users with just an email and password - UserCreationForm

我需要僅使用emailpassword字段在我的應用程序中創建一個用戶帳戶。 因此,我在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預建類

為了創建用戶,我使用了在django核心中預先構建UserCreationForm

在此類中,使用用戶名字段, 例如此處所示

根據以上所述,在我的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類核心,我強迫使用其中需要用戶UserCreationForm的django核心功能。

如何刪除用戶名或修改用戶名?

我知道不建議修改django核心,但是,如何在不包含使用UserCreationForm django類核心的用戶UserCreationForm段的情況下創建用戶?

我嘗試在創建用戶的地方覆蓋表單的保存方法,但是我不清楚流程,我認為不便之處在於使用UserCreationForm django類core ..

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

如果有人能指出我正確的方向,將不勝感激。 :)

我找到了可行的解決方案。

無論如何,請隨時提出更好的解決方案!

就像我的不便/錯誤與在django核心中預先構建UserCreationForm類的使用有關,該類在其邏輯中使用username字段 ,然后我繼續進行以下操作:

在我的類CustomUserCreationForm是UserCreationForm類的子類,我使用email字段而非username UserCreationForm將屬性fields覆蓋/添加到了Meta類。 這個問題帖子可以幫助我。

我的類CustomUserCreationForm保持如下:

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模型的屬性。 這意味着即使我用email字段覆蓋了fields值,Django仍然嘗試詢問用戶email段。

當然這是邏輯,因為我仍然從Django核心中預先構建的 UserCreationForm類繼承

然后,我使用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 ...

而且我的用戶UserCreateForm段仍保留在我的自定義用戶架構中,這不是必需的,並且當我從繼承自UserCreationForm UserCreateForm類創建用戶時,我可以僅使用電子郵件和密碼來創建用戶帳戶

在此處輸入圖片說明

我不知道這是否是解決此不便的最佳方法。 隨時提出改進建議!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM