AbstractBaseUserクラスを使用してカスタムユーザーモデルを作成しました。同じコードがここにあります。Djangoでカスタム認証バックエンドを使用できません
class UserModel(AbstractBaseUser):
user_type_choices = (
(constants.USER_TYPE_ADMIN, 'Admin'),
(constants.USER_TYPE_INSTITUTE, 'Institute'),
(constants.USER_TYPE_STUDENT, 'Student')
)
sys_id = models.AutoField(primary_key=True, blank=True)
name = models.CharField(max_length=127, null=False, blank=False)
email = models.EmailField(max_length=127, unique=True, null=False, blank=False)
mobile = models.CharField(max_length=10, unique=True, null=False, blank=False)
user_type = models.PositiveSmallIntegerField(choices=user_type_choices, null=False, blank=True, help_text="Admin(1)/Institute(2)/Student(3)")
access_valid_start = models.DateTimeField(null=True, blank=True)
access_valid_end = models.DateTimeField(null=True, blank=True)
created_when = models.DateTimeField(null=True, blank=True)
created_by = models.BigIntegerField(null=True, blank=True)
last_updated_when = models.DateTimeField(null=True, blank=True)
last_updated_by = models.BigIntegerField(null=True, blank=True)
notes = models.CharField(max_length=2048, null=True, blank=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=True)
objects = MyUserManager()
USERNAME_FIELD = "email"
# REQUIRED_FIELDS must contain all required fields on your User model,
# but should not contain the USERNAME_FIELD or password as these fields will always be prompted for.
REQUIRED_FIELDS = ['name', 'mobile', 'user_type']
class Meta:
app_label = "accounts"
db_table = "users"
def __str__(self):
return self.email
def get_full_name(self):
return self.name
def get_short_name(self):
return self.name
def is_access_valid(self):
if self.access_valid_end > utility.now():
return True
else:
return False
def save(self, *args, **kwargs):
if not self.sys_id:
self.created_when = utility.now()
self.last_updated_when = utility.now()
return super(UserModel, self).save(*args, **kwargs)
マネージャーのコードは以下のとおりです。
class MyUserManager(BaseUserManager):
use_in_migrations = True
def create_user(self, email, name, mobile, user_type, password):
return create_superuser(self, email, name, mobile, user_type, password)
# python manage.py createsuperuser
def create_superuser(self, email, name, mobile, user_type, password):
user = self.model(
email = email,
name = name,
mobile = mobile,
user_type = user_type,
access_valid_start = utility.now(),
access_valid_end = utility.get_access_end_date(),
created_when = utility.now(),
created_by = constants.COMMAND_LINE_USER_ID,
last_updated_when = utility.now(),
last_updated_by = constants.COMMAND_LINE_USER_ID,
notes = 'This user is created from command line. createsuperuser utility.'
)
user.set_password(password)
user.save(using=self._db)
return user
また、認証バックエンドも作成しました。
class MyAuthBackend(object):
def authenticate(self, email, password):
try:
user = UserModel.objects.get(email=email)
if user.check_password(password):
return user
else:
return None
except UserModel.DoesNotExist:
logging.getLogger("error_logger").error("user with login %s does not exists " % login)
return None
except Exception as e:
logging.getLogger("error_logger").error("user with login %s does not exists " % login)
return None
def get_user(self, user_id):
# user_id must be the primary key of table.
try:
user = UserModel.objects.get(sys_id=user_id)
if user.is_active:
return user
return None
except UserModel.DoesNotExist:
logging.getLogger("error_logger").error("user with %(user_id)d not found")
return None
設定ファイルにカスタムユーザーモデルとバックエンドを含めました。
AUTH_USER_MODEL = 'accounts.UserModel'
AUTHENTICATION_BACKENDS = ('accounts.backends.MyAuthBackend',)
私は、コマンドラインからスーパーユーザを作成しましたが、私は管理者のログインURLからログインしようとしたとき、次のエラーがスローされました。 'UserModel' object has no attribute 'has_module_perms'
:
Please enter the correct email and password for a staff account. Note that both fields may be case-sensitive.
としてはthis SO answerで、私はフォールバック認証バックエンドを使用して、それがこのエラーを投げ始め示唆しています。これは、フォールバックバックエンドがここで働いたことを意味します。しかし、以下の機能をカスタムユーザモデルに追加する必要がありました。
さらに、is_superuserフィールドも追加されました。今それは正常に動作しています。
だから私は質問の下に持っている:私は管理パネルからログインしようとしたときに、カスタムのバックエンドを使用してユーザーを認証することはできませんよ、なぜ
- ?
- なぜ機能has_perm、
is_staff
とis_superuser
のフィールドは管理パネルからのログインに必須ですか? - なぜ、has_perm関数、is_staff、およびis_superuserフィールドは、自分のログインフォームからログインするときに必須ではないのですか?