Что в данном случае делегирует super?

Помогите пожалуйста начинающему разработчику-самоучке с кодом. Как в данной ситуации работает super()? Почему мы наследуемся от класса LoginForm и какого-то объекта self? Насколько я понял мы получаем каким-то образом данные (в виде объекта), а потом с помощью clean() получаем данные в чистом виде.

Вот весь код:

class LoginForm(forms.Form):
    username = forms.CharField(label='Введите Ваш логин')
    password = forms.CharField(label='Введите Ваш пароль', widget=forms.PasswordInput)

    def clean(self):
        cleaned_data = super(LoginForm, self).clean()
        username = self.cleaned_data['username']
        password = self.cleaned_data['password']
        if not User.objects.filter(username=username).exists():
            raise forms.ValidationError('Пользователь с таким логином не зарегистрирован!')

        user = User.objects.get(username=username)
        if user and not user.check_password(password):
            raise forms.ValidationError('Неверный пароль!')

Из него непонятный строки:

cleaned_data = super(LoginForm, self).clean()
username = self.cleaned_data['username']

Пройдёмся по порядку:

class LoginForm(forms.Form):
        ...
    def clean(self):
        cleaned_data = super(LoginForm, self).clean()
  1. Форма super(LoginForm, self) в общем-то избыточна, обычно в этом случае используют просто super() - это в точности тоже самое
  2. По сути мы тут получаем доступ к нашему объекту self класса LoginForm, так, как будто это объект класса-родителя, т.е. класса forms.Form
  3. Мы и так имеем доступ к методам и полям, унаследованным от класса-предка, проблема тут возникает в случае перекрытия методов предка методами потомка с теми же названиями
  4. Таким образом, нам приходится использовать super(), потому что и в нашем текущем класса LoginForm и в классе-родителе forms.Form есть метод clean и мы поэтому не можем его вызвать просто как self.clean() - в этом случае у нас вызовется метод потомка, который перекрыл метод родителя.

Итого - мы вызвали метод clean класса-родителя (передав ему экземпляр нашего класса), он что-то сделал внутри себя и вернул нам некие данные, которые мы положили в переменную cleaned_data.

        username = self.cleaned_data['username']
        password = self.cleaned_data['password']

А вот это смешно - мы тут же забыли про нашу переменную cleaned_data и вместо этого пользуемся теми данными, которые метод clean видимо создал в самом классе в виде поля self.cleaned_data (и потом видимо их ещё и вернул из метода clean()).

Ну, видимо, такая небрежность программиста. Неиспользуемая переменная - это нехороший признак, значит программист не совсем контролирует свои данные и не до конца понимает, что он с ними хочет делать. Если возвращаемые данные не нужны - можно их было просто не получать из метода и никуда не присваивать. Но тут они по идее нужны, а вместо готовых данных в локальной переменной он достаёт ещё раз эти данные из поля класса. Выглядит неаккуратно и запутывает читающего код, кроме того.

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