アプリケーションのカスタムユーザーモデルとカスタム認証を実装しようとしています。
私はモデルを作成して移行を行うことができます。カスタムユーザモデルとカスタム認証がdjangoで動作しません。認証フォームが検証テストに合格していません
from django import forms
from accounts.models import UserModel
class AuthenticationForm(forms.Form):
login = forms.CharField(max_length=128, required=True)
password = forms.CharField(max_length=128, required=True)
:
from django.shortcuts import render_to_response, redirect, render
from django.template import RequestContext
from django.contrib.auth import login, logout , authenticate
from accounts.forms import AuthenticationForm
from django.contrib.auth.decorators import login_required
def accounts_login(request):
context = {}
if request.method == "POST":
form = AuthenticationForm(request.POST) #getting error here
print(form)
if form.is_valid():
user = authenticate(login = request.POST["login"], password = request.POST["password"])
if user is not None:
print(user)
login(request,user)
next_url = request.POST["next"]
return redirect(next_url, args=(), kwargs={})
#more code - not required here. Let me know if needed.
認証フォーム - 私は、ユーザーを認証しています
login
User model with this Login already exists.
ビュー - 私はフォームを作成し、ログインテンプレートを実装する場合でも、私はこのエラーを取得しています
私のカスタムユーザーモデルとユーザーマネージャー -
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.utils import timezone
from django.db.models import Max
class MyUserManager(BaseUserManager):
use_in_migrations = True
def create_user(self,login, parent_type, last_name, first_name, password):
return create_superuser(self,login, parent_type, last_name, first_name, password)
def create_superuser(self,login, parent_type, last_name, first_name, password):
maxx = self.model.objects.all().aggregate(Max('sys_id'))
print(maxx)
user = self.model(
sys_id = maxx["sys_id__max"] + 1,
login = login,
password = password,
parent_type = parent_type,
last_name = last_name,
first_name = first_name,
display_name = last_name + " " + first_name,
created_when = timezone.now()
)
user.save(using=self._db)
# no difference here...actually can set is_admin = True or something like that.
return user
class UserModel(AbstractBaseUser):
# custom user class
SYSTEM = 0
TENANT = 1
parent_type_choices = (
(SYSTEM, 'System'),
(TENANT, 'Tenant')
)
sys_id = models.BigIntegerField(primary_key=True, blank=True)
parent_type = models.PositiveIntegerField(choices=parent_type_choices, null=False, blank=False)
parent_sys_id = models.ForeignKey('tenant.TenantModel', on_delete = models.SET_NULL, null=True, blank=True)
last_name = models.CharField(null=False, blank=False, max_length=40)
first_name = models.CharField(max_length=40, null=False, blank=False)
display_name = models.CharField(max_length=80, unique=True, null=False, blank=True)
login = models.CharField(max_length=40, unique=True, null=False, blank=False)
authentication_method = models.CharField(max_length=80, null=True, blank=True)
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)
objects = MyUserManager()
USERNAME_FIELD = "login"
# 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 = ['parent_type', 'last_name', 'first_name']
class Meta:
app_label = "accounts"
db_table = "Users"
def __str__(self):
return self.display_name
def get_full_name(self):
return self.display_name
def get_short_name(self):
return self.last_name
def check_password(self,password):
return True
if self.password ==password:
return true
カスタムバックエンドsetting.pyでこれらの2つの変数を追加しました
from django.conf import settings
from accounts.models import UserModel
class MyAuthBackend(object):
def authenticate(self, login, password):
try:
user = UserModel.objects.get(login=login)
if user.check_password(password):
return user
else:
print("wrong password")
return None
except User.DoesNotExist:
return None
except Exception as e:
print(repr(e))
return None
def get_user(self, user_id):
try:
user = User.objects.get(pk=user_id)
if user.is_active:
return user
return None
except User.DoesNotExist:
return None
コマンドラインからバックエンドを取得
AUTH_USER_MODEL = 'accounts.UserModel'
AUTHENTICATION_BACKENDS = ('accounts.backends.MyAuthBackend',)
>>> get_backends()
[<accounts.backends.MyAuthBackend object at 0x7f2c438afe80>]
usernameを持つユーザーは、xyzとパスワード 'ABC'がdbに存在します。
1.私は、既存のユーザー名とパスワードでログインしようとしていた場合、それは私が非既存のユーザ名とパスワード(XYZ123を言うことができます)でログインしようとすると、それは私がauthenticate() takes 0 positional arguments but 2 were given
をエラースロー私はUser model with this Login already exists.
2.例外Error私は複数の記事に続いていましたが、主にこれについてはdjangoの公式文書です。問題を解決するために複数の記事を読むが、失敗した。
私が間違っていることを提案してください。
更新1:AuthenticationFormをModelFormから通常のFormクラスに変更しました。エラー1が解決されました。
更新2:私のカスタムバックエンドをDanielが指摘しているように使用していないので、新しいことは何もしていないので役に立たない。したがって、エラー2も解決される。
更新3:スーパーユーザー機能の作成時にユーザーをdbに保存する前にパスワードをハッシュしました。 user.set_password(password)
大変ありがとうございます。私はそれらを修正し、物事は現在うまくいっています。私はあなたが質問を落としたとは思わない? – User42