У объекта 'SignInForm' нет атрибута 'request'

Я пытаюсь установить remember_me в forms.py вместо views.py через def clean_remember_me. но это не работает и выдает ошибку

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

В django обычно нет необходимости использовать request. По умолчанию в Django нет request.

В моих проектах мне нравится инициировать форму с запросом в инициалах:

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

после, в примере формы вы можете использовать его как:

request = self.initial['request']

Для вашего примера вы можете переопределить в вашем представлении метод get_initial:

class LogInView(...):

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

Но согласно Django-way-программированию, делать это нужно не в методе clean_field формы. Потому что если форма не walid, то изменения в request.settings уже сделаны. Это неправильно. Вместо того, чтобы делать что-то в форме, нужно использовать эту логику в 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)

В этом случае сессия будет очищена только в том случае, если все данные верны. И, конечно, в этом случае вам не нужен запрос в форме.

Вам нужно передать запрос в форму следующим образом:

[your_form_class](request.POST, request=request)

А в классе вашей формы:

def __init__(self, *args, **kwargs):
        self.request = kwargs.pop("request") # store value of request 
        print(self.request.user) 
        super().__init__(*args, **kwargs)

А затем вы можете сделать:

def clean_remember_me(self):
        remember_me = self.cleaned_data['remember_me']
        if not remember_me:
            self.request.session.set_expiry(0)

Надеюсь, это поможет вам.

Вернуться на верх