Search code examples
djangodjango-viewsdjango-forms

'SignInForm' object has no attribute 'request'


I'm trining to set remember_me in forms.py insted of views.py via def clean_remember_me. but it dosn't work and give me error !

forms.py

class SignInForm(forms.Form):
    remember_me = forms.BooleanField(widget=forms.CheckboxInput(),label=_('Remember me'), required=False)
    def clean_remember_me(self):
        remember_me = self.cleaned_data['remember_me']
        if not remember_me:
            self.request.session.set_expiry(0)

views.py

class LogInView(GuestOnlyView, FormView):
    template_name = 'log_in.html'
    form_class = SignInForm

Solution

  • In django usually you don't need to use request. By default Django dont have request.

    in my projects i like to initiate form with request in initial's:

    Myform(data, initial={..., 'request':request, ...}) 
    

    after, in form instance you can use it as:

    request = self.initial['request']
    

    For your example you can override in your view get_initial method:

    class LogInView(...):
    
        def get_initial(self, *args, **kwargs):
            return super().get_initial(*args, **kwargs) | {'request': self.request}
    

    But according to Django-way-programming, you should do it not in the clean_field method of the form. Because if the form is not walid, then the changes to request.settings are already done. This is wrong. Instead to do something in form, you should use this logic in View:

    class LogInView(...):
        def form_valid(self, form, *args, **kwargs):
            if not form.cleaned_data.get('remember_me'):
                self.request.session.set_expiry(0)
            return super().form_valid(form, *args, **kwargs)
    

    In this case, the session will only be cleared if all data is correct. And, of course, in this case you don't need to have a request in the form.