Заметил в Sentry на тестовом сервере следующую ошибку:
AttributeError: 'NoneType' object has no attribute 'rfind'
Request Method: POST
Request URL: http://test.andrgavr.com/rfi/commercial/
Exception Value:
'NoneType' object has no attribute 'rfind'
Exception Location: /usr/local/lib/python2.7/posixpath.py in basename, line 112
Environment:
Request Method: POST
Request URL: http://test.andrgavr.com/rfi/commercial/
Traceback:
File "/home/sag/site2/env/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "/home/sag/site2/src/frontend/views.py" in rfi
591. form.save()
File "/home/sag/site2/env/lib/python2.7/site-packages/django/forms/models.py" in save
364. fail_message, commit, construct=False)
File "/home/sag/site2/env/lib/python2.7/site-packages/django/forms/models.py" in save_instance
86. instance.save()
File "/home/sag/site2/env/lib/python2.7/site-packages/django/db/models/base.py" in save
463. self.save_base(using=using, force_insert=force_insert, force_update=force_update)
File "/home/sag/site2/env/lib/python2.7/site-packages/django/db/models/base.py" in save_base
565. created=(not record_exists), raw=raw, using=using)
File "/home/sag/site2/env/lib/python2.7/site-packages/django/dispatch/dispatcher.py" in send
172. response = receiver(signal=self, sender=sender, **named)
File "/home/sag/site2/src/rfi/models.py" in notify_commercial
145. attachment = (basename(instance.addons.name), instance.addons.read())
File "/usr/local/lib/python2.7/posixpath.py" in basename
112. i = p.rfind('/') + 1
Exception Type: AttributeError at /rfi/commercial/
Exception Value: 'NoneType' object has no attribute 'rfind'
Судя по тексту, переданного формой, до сайта добрались боты и начали стучатся во все двери.
Присмотревшись, понял, что ошибка не у меня, а у Django. Поглядел на форму на странице и понял, что сносят страницу через явную подстановку бреда вместо имени файла. Это приводит к тому, что на сервер ничего в поле FileField
не передаётся. Это и приводит к ошибке.
Лечится довольно просто -- через дополнительную проверку:
def clean_addons(self):
value = self.cleaned_data.get('addons')
if not value:
raise forms.ValidationError(_('Choose a file, please.'))
return value