前提・実現したいこと
python Djangoで管理システムを構築しています。
ユーザー管理でauthパッケージをカスタムしているのですが、新規登録時と更新時にパスワードが暗号化されなく困っております。
python manage.py createsuperuser を叩くとhash化されますが、web上で更新/登録するとhash化されずにそのままテーブルに入ります。
forms.pyの修正やライブラリーなどを変えてみましたがpython初学者の為よく分かりません。
調べたところ forms.py か models.py に set_password() を書けば良さそうとあるのですが、どこにどう書けば良いか分かりませんでした。
どなたかご教示お願い致します。
accounts/views.py
from django.shortcuts import render, resolve_url from django.views import generic from django.urls import reverse_lazy, reverse from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.views import ( LoginView, LogoutView ) from pure_pagination.mixins import PaginationMixin from .models import User from .forms import LoginForm, UserEditForm class UserUpdateView(LoginRequiredMixin, generic.UpdateView): # 更新 model = User fields = ('email', 'password') update_form = UserEditForm template_name = 'accounts/update.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['comp'] = self.kwargs.get('comp') return context def get_success_url(self): return reverse('accounts:user_update', kwargs={'pk': self.object.id, 'comp': 1}) class UserCreateView(LoginRequiredMixin, generic.CreateView): # 作成 model = User fields = ('email', 'password') create_form = UserEditForm template_name = 'accounts/create.html' def get_success_url(self): return reverse('accounts:user_list', kwargs={'create_comp': 1})
accounts/forms.py
from django.contrib.auth.forms import ( AuthenticationForm ) from django import forms from .models import User class UserEditForm(forms.ModelForm): password = forms.CharField(label='Password', widget=forms.PasswordInput) class Meta: model = User fields = ('email',) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) for field in self.fields.values(): field.widget.attrs["class"] = "form-control" def clean_password(self): password = self.cleaned_data.get("password") return password def save(self, commit=True): user = super().save(commit=False) user.set_password(self.cleaned_data["password"]) if commit: user.save() return user
accounts/models.py
from django.contrib.auth.models import AbstractBaseUser, UserManager, PermissionsMixin from django.db import models from django.utils.translation import gettext_lazy as _ from django.core.mail import send_mail from django.utils import timezone class UserManager(UserManager): def _create_user(self, email, password, **extra_fields): 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_user(self, email, password=None, **extra_fields): extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', False) return self._create_user(email, password, **extra_fields) def create_superuser(self, email, password, **extra_fields): 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, password, **extra_fields) class User(AbstractBaseUser, PermissionsMixin): email = models.EmailField(_('email address'), unique=True) is_staff = models.BooleanField( _('staff status'), default=False, help_text=_('Designates whether the user can log into this admin 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.' ), ) date_joined = models.DateTimeField(_('date joined'), default=timezone.now) objects = UserManager() EMAIL_FIELD = 'email' USERNAME_FIELD = 'email' REQUIRED_FIELDS = [] class Meta: verbose_name = _('user') verbose_name_plural = _('users') def clean(self): super().clean() self.email = self.__class__.objects.normalize_email(self.email) # 多分ここで set_password するのかと思うのですが、上手く出来ません # self.password = '1234abcd' def email_user(self, subject, message, from_email=None, **kwargs): """Send an email to this user.""" send_mail(subject, message, from_email, [self.email], **kwargs)
config/settings.py
~~省略~~ INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'bootstrap4', 'debug_toolbar', 'accounts', ] PASSWORD_HASHERS = [ # ↓はエラーが出た為コメントアウトしました # 'django.contrib.auth.hashers.Argon2PasswordHasher', 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', 'django.contrib.auth.hashers.BCryptPasswordHasher', 'django.contrib.auth.hashers.PBKDF2PasswordHasher', 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher', ] AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] AUTH_USER_MODEL = 'accounts.User' ~~省略~~
試したこと
forms.py と models.py にset_password を使って記述
(どう書いて良いか分からないです)
補足情報(FW/ツールのバージョンなど)
python 3.6.6
Django 2.2.4
あなたの回答
tips
プレビュー