Что в данном случае делегирует 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()
- Форма
super(LoginForm, self)
в общем-то избыточна, обычно в этом случае используют простоsuper()
- это в точности тоже самое - По сути мы тут получаем доступ к нашему объекту
self
классаLoginForm
, так, как будто это объект класса-родителя, т.е. классаforms.Form
- Мы и так имеем доступ к методам и полям, унаследованным от класса-предка, проблема тут возникает в случае перекрытия методов предка методами потомка с теми же названиями
- Таким образом, нам приходится использовать
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()
).
Ну, видимо, такая небрежность программиста. Неиспользуемая переменная - это нехороший признак, значит программист не совсем контролирует свои данные и не до конца понимает, что он с ними хочет делать. Если возвращаемые данные не нужны - можно их было просто не получать из метода и никуда не присваивать. Но тут они по идее нужны, а вместо готовых данных в локальной переменной он достаёт ещё раз эти данные из поля класса. Выглядит неаккуратно и запутывает читающего код, кроме того.