[Answer]-Django app login โ€“ Can I require user to enter email and password only and then lookup username prior to form validation?

1๐Ÿ‘

โœ…

You can tweak your user model to do this. Have your user model extend AbstractBaseUser with USERNAME_FIELD = 'email'. So now you are using the email as the unique identifier, instead of username. This does not mean you cannot have a username anymore, it just does not need to be unique (but it still can).

Now create a form for your login page that only requires an email and password from the user:

Form

class MyLoginForm(forms.Form):

    email = forms.EmailField(widget=EmailInput(attrs={
        'required': 'required',
        'placeholder': ('Email'),
    }))

    password = forms.CharField(widget=forms.PasswordInput(attrs={
        'required': 'required',
        'placeholder': ('Password'),
    }))

    error_messages = {
        'invalid_login': ('Please ensure you entered the correct email and password.'),
    }

    def __init__(self, *args, **kwargs):
        self.user_cache = None
        super(MyLoginForm, self).__init__(*args, **kwargs)

    def clean(self):
        email = self.cleaned_data.get('email')
        password = self.cleaned_data.get('password')

        if email and password:
            self.user_cache = authenticate(email=email, password=password)
            if self.user_cache is None:
                raise forms.ValidationError(self.error_messages['invalid_login'])

        return self.cleaned_data

    def get_user(self):
        return self.user_cache

view

class MyLoginView(DjangoTemplateView):

    template_name = 'my/login.html'

    def dispatch(self, request):
        if request.user.is_authenticated():
            return redirect('some-page')
        return super(MyLoginView, self).dispatch(request)

    def get(self, request):
        return self.render_to_response({
            'form': MyLoginForm()
        })

    def post(self, request):
        form = MyLoginForm(data=request.POST)
        if form.is_valid():
            login(request, form.get_user())
            next = request.POST.get('next', reverse('some-page'))
            return redirect(next)
        return self.render_to_response({
            'form': form,
        })
๐Ÿ‘คquaspas

Leave a comment