質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

2538閲覧

djangoにおいて独自のユーザーモデルを用いるときのmodelの作成方法

sarusnnn

総合スコア1

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/08/03 05:51

編集2021/08/09 07:34

前提・実現したいこと

独自のモデルを用いて,authenticateを使うために,認証バックエンドをカスタマイズしていました

発生している問題・エラーメッセージ

エラーがUserdataにcheck_passwordが定義されていないからこういった問題が起こったという風に記載されていることはわかります。ただ,参考サイトの方でもUserにcheck_passwordが設定されていないのに,自分のmodelの場合こういったエラーが生じるのかわかりません。また,具体的にどのようにcheck_passwordを導入したらいいのかもわからないのでその点もご教授お願い致します。

 User

File "C:\Users\ユーザー名\testapp\content\backends.py", line 11, in authenticate if user.check_password(password) and self.user_can_authenticate(user): AttributeError: 'Userdata' object has no attribute 'check_password'

該当のソースコード

backends.py

from django.contrib.auth.backends import ModelBackend from .models import Userdata class Userbackend(ModelBackend): def authenticate(self,request,email=None,password=None,**kwargs): try: user=Userdata.objects.get(email=email) except Userdata.DoesNotExist: return None else: if user.check_password(password) and self.user_can_authenticate(user): return user

models.py

#ユーザー登録 class Userdata(models.Model): name = models.CharField(verbose_name='ユーザー名',max_length=15,unique=True) email = models.EmailField(verbose_name='ユーザーid',max_length=30,unique=True) password = models.CharField(verbose_name='パスワード',max_length=15) regist_date = models.DateTimeField(default=timezone.now)

試したこと

次のサイトを参考にし認証バックエンドをカスタマイズしていました。
(https://django.kurodigi.com/customize-auth-backend/)

参考サイトのmodels.pyが別のページにありましたので下記のサイトを参考に指定ください
(https://django.kurodigi.com/custamize-user/)

補足情報(FW/ツールのバージョンなど)

ディレクトリ構成
testapp/
├ content/
│ ├ backends.py
│ ├models.py

Python 3.9.5
django 3.2.5

参考サイトのbackends.pyとmodels.pyの該当箇所と思われる箇所のコードは次のようになっていました。
backend.py

from django.contrib.auth.backends import ModelBackend from .models import User class EmailAuthBackend(ModelBackend): def authenticate(self, request, email=None, password=None, **kwargs): try: user = User.objects.get(email=email) except User.DoseNotExist: return None else: if user.check_password(password) and self.user_can_authenticate(user): return user

models.py

class User(AbstractBaseUser, PermissionsMixin): """ Django標準のUserをベースにカスタマイズしたUserクラス """ username_validator = UnicodeUsernameValidator() # python3で半角英数のみ許容する場合はASCIIUsernameValidatorを用いる # username_validator = ASCIIUsernameValidator() username = models.CharField( _('username'), max_length=50, unique=True, # help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'), help_text='この項目は必須です。全角文字、半角英数字、@/./+/-/_ で50文字以下にしてください。', validators=[username_validator], error_messages={ 'unique': _("A user with that username already exists."), }, ) # first_name = models.CharField(_('first name'), max_length=30, blank=True) # last_name = models.CharField(_('last name'), max_length=150, blank=True) email = models.EmailField( _('email address'), help_text='この項目は必須です。メールアドレスは公開されません。', blank=False ) 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 = 'username' REQUIRED_FIELDS = ['email'] class Meta: verbose_name = _('user') verbose_name_plural = _('users') # abstract = True abstract = False def clean(self): super().clean() self.email = self.__class__.objects.normalize_email(self.email) # first_nameとlast_nameに関する部分はコメントアウト # def get_full_name(self): # """ # Return the first_name plus the last_name, with a space in between. # """ # full_name = '%s %s' % (self.first_name, self.last_name) # return full_name.strip() # def get_short_name(self): # """Return the short name for the user.""" # return self.first_name 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)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

UserdataにAbstractBaseUserを継承されるのが良いかと思います。

python

1#ユーザー登録 2class Userdata(AbstractBaseUser): 3 name = models.CharField(verbose_name='ユーザー名',max_length=15,unique=True) 4 email = models.EmailField(verbose_name='ユーザーid',max_length=30,unique=True) 5 password = models.CharField(verbose_name='パスワード',max_length=15) 6 regist_date = models.DateTimeField(default=timezone.now)

投稿2021/08/05 11:32

holy_

総合スコア364

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sarusnnn

2021/08/06 02:52

ご回答いただき,ありがとうございます。実行してみようと思います
guest

0

自己解決

modelsの最終的な形として次のような書き方をしたところ解決しました。

#ユーザー登録 class UserManager(BaseUserManager): use_in_migrations=True#migration時に特殊な操作をするとき必要なのでなくても構わない  #一般ユーザーの動作 def create_user(self,username,email,date,password=None): if not username: raise ValueError('The given username must be set') elif not email: raise ValueError('The given email must be set') user = self.model( name=username, email = self.normalize_email(email), regist_date=date, ) user.set_password(password) user.save(using=self._db) return user #superuserの動作 def create_superuser(self,username,email,password): user=self.create_user( username, email, password=password ) user.is_admin =True user.save(using=self._db) return user class Userdata(AbstractBaseUser,PermissionsMixin):  #使いたい独自のmodel name = models.CharField(verbose_name='ユーザー名',max_length=50,unique=True) email = models.EmailField(verbose_name='ユーザーid',max_length=30,unique=True) password = models.CharField(verbose_name='パスワード',max_length=15) date_joined = models.DateTimeField(default=timezone.now) is_staff = models.BooleanField(default=False) is_active = models.BooleanField(default=True) #Userdata.objects.all()とかで使うobjects objects=UserManager() EMAIL_FIELD = 'email'#(ユーザーがパスワード変更時にemailでのチェック可能とするために必要) USERNAME_FIELD = 'email'#(認証に使いたいものを記載                 username認証の場合:USERNAME_FIELD = 'username' email認証の場合: USERNAME_FIELD = 'email'                ) REQUIRED_FIELDS = []#createsuperuserの時に聞かれる追加項目

投稿2021/08/07 21:46

編集2021/08/09 07:32
sarusnnn

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

AttributeError: 'Userdata' object has no attribute 'check_password'

'Userdata' オブジェクトには、'check_password'というアトリビュートがない、とおっしゃってます。
そいつはどこで定義なさってるんでしょうか。

投稿2021/08/03 06:58

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sarusnnn

2021/08/03 07:30

ご対応いただきありがとうございます。説明不足でも仕分けございません。補足させていただきますと,  エラーがUserdataにcheck_passwordが定義されていないからこういった問題が起こったという風に記載されていることはわかるのですが,参考サイトの方でもUserにcheck_passwordが設定されていないのに,自分のmodelの場合こういったエラーが生じるのかわかりません。また,具体的にどのようにcheck_passwordを導入したらいいのかもわからないのでその点もご教授お願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問