Home > Mobile >  Unable to log in with email in django
Unable to log in with email in django

Time:10-05

I have created custom user model but unable to login with valid email id and password

added user manager too. Is there any problem in user manager. Also i have added AUTH_USER_MODEL in settings.py

models.py


class UserManager(BaseUserManager):
    def create_user(self, email, password=None):
        """
        Creates and saves a User with the given email and password.
        """
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=self.normalize_email(email),
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_staffuser(self, email, password):
        """
        Creates and saves a staff user with the given email and password.
        """
        user = self.create_user(
            email,
            password=password,
        )
        user.staff = True
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password):
        """
        Creates and saves a superuser with the given email and password.
        """
        user = self.create_user(
            email,
            password=password,
        )
        user.staff = True
        user.admin = True
        user.save(using=self._db)
        return user


class User(AbstractBaseUser):
    email = models.EmailField(verbose_name='email address',
        max_length=255,
        unique=True,
    )
    is_active = models.BooleanField(default=True)
    staff = models.BooleanField(default=False) # a admin user; non super-user
    admin = models.BooleanField(default=False) # a superuser

    objects = UserManager()

    # notice the absence of a "Password field", that is built in.

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

methods like has_perm,has_module_perm are written.

forms.py

This is register form

from django import forms
from django.contrib.auth import get_user_model


User = get_user_model()


class RegisterForm(forms.ModelForm):

    password = forms.CharField(widget=forms.PasswordInput(attrs={'class':'form-control'}))
    password_2 = forms.CharField(label='Confirm Password',widget=forms.PasswordInput(attrs={'class':'form-control'}))

    class Meta:
        model = User
        fields = ['email','password','password_2']

        labels = {
            'email':'Email Id',
            'password':'Password',
        }


        widgets = {
            'email':forms.EmailInput(attrs={'class':'form-control'}),            
        }

    
    def clean_email(self):
        '''
        Verify email is available.
        '''
        email = self.cleaned_data.get('email')
        qs = User.objects.filter(email=email)
        if qs.exists():
            raise forms.ValidationError("Email is taken")
        return email

    def clean(self):
        '''
        Verify both passwords match.
        '''
        cleaned_data = super().clean()
        password = cleaned_data.get("password")
        password_2 = cleaned_data.get("password_2")
        if password is not None and password != password_2:
            self.add_error("password_2", "Your passwords must match")
        return cleaned_data

forms.py

class AuthenticationForm(forms.Form): 
    email = forms.EmailField(widget=forms.TextInput(
        attrs={'class': 'form-control','type':'text','name': 'email','placeholder':'Email'}), 
        label='Email')
    password = forms.CharField(widget=forms.PasswordInput(
        attrs={'class':'form-control','type':'password', 'name': 'password','placeholder':'Password'}),
        label='Password')

    class Meta:
        fields = ['email', 'password']

this is register view. Updated the post

def registerEmployeeView(request):

    if request.method == "POST":
        form = RegisterForm(request.POST)

        if form.is_valid():

            form.save()
            messages.success(request,'Employee Register Successfully')
            return redirect('login-employee')
    
    else:
        form = RegisterForm()

    context = {
        'form':form,
    }

    return render(request,'accounts/register.html',context)

views.py

def loginEmployeeView(request):
    if request.method == 'POST':
        form = AuthenticationForm(data = request.POST)
        if form.is_valid():
            print("1")
            email = request.POST.get('email')
            password = request.POST.get('password')
            print("2")
            user = authenticate(email=email, password=password)
            print("3")
            if user is not None:
                if user.is_active:
                    print("4")
                    login(request,user)
                    messages.success(request,'Logged in successfully')
                    return redirect('dashboard') 

                else:
                    messages.error(request,'user is not active')
                    return redirect('login-employee')
            
            else:
                messages.error(request,'invalid username or password')
                return redirect('login-employee')

    else:
        print("5")
        form = AuthenticationForm()

    return render(request,'accounts/login.html',{'form':form,})

I tried to logged in with valid information still it shows invalid username or password. Thank you.

CodePudding user response:

You should use a different authentication backend that checks the credentials with the given user object. Such backend can look like:

# app_name/backend.py

from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend

UserModel = get_user_model()

class EmailBackend(ModelBackend):

    def authenticate(self, request, email=None, password=None):
        try:
            user = UserModel.objects.get(email=email)
        except UserModel.DoesNotExist:
            UserModel().set_password(password)
            return None
        if user is not None and user.check_password(password):
            if user.is_active:
                return user
        return None

Then in the settings file you should use the EmailBackend for the AUTHENTICATION_BACKENDS setting [Django-doc]:

# settings.py

# ⋮
AUTHENTICATION_BACKENDS = [
    'app_name.backends.EmailBackend'
]
# ⋮

Finally your Form should make use of the .create_user(…) method, or work with .set_password():

class RegisterForm(forms.ModelForm):
    # ⋮

    def save(self, commit=True):
        user = super().save(commit=False)
        user.set_password(self.cleaned_data['password1'])
        if commit:
            user.save()
        return user
  • Related