2017-10-24 16 views
0

ユーザー名を使用してユーザーにログインさせる必要はありません。メールのみ。カスタムユーザーモデル用に電子メールでログインする適切な方法は何ですか?

class User(AbstractBaseUser, PermissionsMixin): 
    email = models.EmailField('email address', unique=True) 
    accepted = models.BooleanField('status', default=False) 
    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.', 
    ) 
    USERNAME_FIELD = 'email' 
    REQUIRED_FIELDS = [] 
    objects = MyUserManager() 

    class Meta: 
     verbose_name = 'user' 
     verbose_name_plural = 'users' 

    def __str__(self): 
     return self.email 

    def get_full_name(self): 
     return self.email 

    def get_short_name(self): 
     return self.email 

カスタムマネージャー:

class MyUserManager(BaseUserManager): 
    def _create_user(self, email, password, **extra_fields): 
     if not email: 
      raise ValueError('The Email must be set') 
     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) 

そして、私は、ログインテンプレートをレンダリングするauth_views.loginメソッドを使用しています は、だから私は、カスタムユーザモデルを持っています。 テンプレートには、emailpasswordの2つの入力フィールドがあります。

私がフォームを送信すると、ユーザー名フィールドが必要であるという検証エラーが表示されます。

auth_views.loginは、フィールドが設定されているAuthenticationFormを使用していることがわかりました。

class MyAuthForm(AuthenticationForm): 
    username = forms.EmailField() 

url(r'^login/$', auth_views.login, {'authentication_form': MyAuthForm}, name='login') 

そして、私は、電子メールフィールドに名前としてusername使用したテンプレートで:だから私は、このフォームをオーバーライドし、ビューに渡すことにしました。それは悪臭を覚える。

私の質問はメールで正しくログインする実装ですか?そうでない場合は、適切な方法は何ですか?

アップデート:このすべての目的は、ユーザーが自分の電子メールでログインできるようにする場合には設定

AUTH_USER_MODEL = 'users.User' 
LOGIN_URL = '/login/' 
LOGIN_REDIRECT_URL = 'base:home' 

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend', 
) 
+0

これは、あなたの質問への答えではありませんが、そのような – Selcuk

+0

ができジャンゴ・allauthとして、代わりに自分自身を書くの第三者認証システムを使用する方が簡単ですプロジェクトから 'settings.py'を共有します(資格情報なし)? –

+0

@AbbasovAlexander、done – belek

答えて

0

を追加し、その後、これはすべて、このことなく行うことができます。

djangoデフォルトのUserモデルを使用してください。ユーザーのログイン用のビューとフォーム(電子メールとパスワードのフィールドを含む)を追加します。あなたのビューでは、あなたのユーザーの電子メールを取得した後、彼/彼女のユーザー名のdjangoのUserモデルを照会します。

ユーザーにログインするために、表示内にdjango.contrib.auth.authenticatedjango.contrib.auth.loginなどの組み込み関数を使用します。

+0

ハム、ありがとう!私はこれで間違いなく過ぎ去ったようです。私はあなたのアドバイスを後でチェックするつもりです。 – belek

0

はい、正しい方向です。プロジェクトやデバッグに深く関与することなく、あなたの質問に答えにくいです。

次のDjangoの部分に注意してください。ログインフォームが送信されると、LoginViewはデータをAuthenticationFormに渡します。 AuthenticationFormdef authenticate()と呼び、すべてのバックエンドをsettings.AUTHENTICATION_BACKENDSから調べます。

ここでは、1つのデフォルトバックエンドModelBackendがあります。独自のバックエンドを追加してsettings.AUTHENTICATION_BACKENDSに追加する必要があります。バックエンドはいくつでも構いませんが、順序は関係ありません。たとえば、次のように

AUTHENTICATION_BACKENDS = (
    'your_project.backends.CustomBackend', # will be called before the next 
    'django.contrib.auth.backends.ModelBackend', 
) 

例:

class CustomBackend(ModelBackend): 

    def authenticate(self, **kw): 
     # here you have to return user object or None 
     ... 

    def get_user(self, user_id): 
     try: 
      return User._default_manager.get(pk=user_id) 
     except User.DoesNotExist: 
      return None