'Django AuthenticationForm is not validating and not storing information in database

So basically I'm trying to do a simple login system using Django AuthenticationForm and LoginView. The form takes the user input and when the login button is pressed, the page just reloads, instead of throwing validation errors or logging the user and redirecting him. I've tried to overwrite the clean method but the result is the same. I don't know what I'm doing wrong.

This is the User model:

class StoreUser(auth_models.AbstractBaseUser, auth_models.PermissionsMixin):
  email = models.EmailField(
    unique=True,
)
  date_joined = models.DateTimeField(
    auto_now_add=True,
)

  is_staff = models.BooleanField(
    default=False,
)

  USERNAME_FIELD = 'email'

  objects = StoreUserManager()

Here is the Login view:

class UserLoginView(auth_views.LoginView):
   form_class = UserLoginForm
   template_name = 'store_auth/user_login.html'
   success_url = reverse_lazy('homepage')

And also the Form:

class UserLoginForm(auth_forms.AuthenticationForm):
   email = forms.EmailField(widget=forms.EmailInput(attrs={'class': 'form-control', 'id': "email-login", 'placeholder': "Enter your email",}))
   password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control', 'id':"password-login", 'labels': "Password", 'placeholder': "Enter your password", }))

   class Meta:
    model = StoreUser

And the HTML:

  <form method="post" action="{% url 'user login' %}">
              {% csrf_token %}
            <div class="form-group">
            <label for="email-login">E-Mail</label>
              {{ form.email }}
            </div>
            <div class="form-group">
            <label for="password-login">Password</label>
              {{ form.password }}
            </div>
            <a href="javascript:;">Forgotten Password?</a>
            <div class="padding-top-20">                  
              <button class="btn btn-primary" type="submit">Login</button>
            </div>

When the fields are defined through the Meta class everything works fine, and the user is logged in and redirected successfully, but in this way, the field widgets remain unchanged because Meta is parsed by the metaclass before the init. I also tried to add the field manually to self. fields:

 def __init__(self, *args, **kwargs):
   super(UserLoginForm, self).__init__(*args, **kwargs)
   self.fields['email'] = forms.EmailField(widget=forms.EmailInput(attrs={'class': 'form-control', 'id': "email-login", 'placeholder': "Enter your email",}))
   self.fields['password'] = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control', 'id':"password-login", 'labels': "Password", 'placeholder': "Enter your password", }))

But again and the user is not logged in and the data is not validated. I think my mistake is in the field validation. Аny help will be appreciated, thanks in advance!



Solution 1:[1]

I am not sure why your __init__ method does not work well, but you can add the widget definitions in the Meta class:

class UserLoginForm(auth_forms.AuthenticationForm):
   email = forms.EmailField()
   password = forms.CharField()

   class Meta:
       # AuthenticationForm is not a ModelForm so the line below is
       # invalid. Your User model will be retrieved through the 
       # AUTH_USER_MODEL setting
       # model = StoreUser  
       fields = ['email', 'password']
       widgets = {
           'email': forms.EmailInput(attrs={'class': 'form-control', 'id': "email-login", 'placeholder': "Enter your email",}),
           'password': forms.PasswordInput(attrs={'class': 'form-control', 'id':"password-login", 'labels': "Password", 'placeholder': "Enter your password", })
       }

Let me know if it works :)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 vinkomlacic