Flask #17: Загрузка файлов на сервер и сохранение в БД
ฝัง
- เผยแพร่เมื่อ 18 พ.ค. 2020
- Инфо-сайт: proproprogs.ru
Принцип загрузки файлов на сервер через форму на примере загрузки изображений аватара пользователя и сохранение их в БД.
Проект flasksite: github.com/selfedu-rus/flasks...
Спасибо! Ваши уроки великолепны!
Спасибо за интересный урок!!! отдельное большое спасибо за исходники!!!
Смотрю ваши великолепные уроки и задаюсь вопросом, а за что я вообще деньги в гикбрейнс отдал год назад
Полезная тема!!! Спасибо Вам!!!
У фласка есть уязвимость при загрузке файлов. На Hack The Box есть задача с уязвимым компьютером "OpenSource", там как раз сайт на Flask и можно потренироваться. Также есть уязвимость с подбором pin-а для удаленного дебагера. Собственно с Hack The Box я попал сюда на эти уроки.
Лайк за видео!
а есть способы защититься от этой уязвимости?
@@orthodox-chanel Не ясно, что именно имел в виду комментатор, но возможно, уязвимость связана с сохранением файлов, которые загружает пользователь, в файловую систему. Чтобы от нее защититься, нужно использовать функцию werkzeug.utils.secure_filename(filename: str) -> str, которая возвращает безопасное имя файла. Автор ролика про эту функцию не сказал, но и в уроке файл сохраняется в базу данных, поэтому ее не нужно было использовать.
если работаете с постгрес и фото не хочет отображаться то нужно его преобразовать в байтовый вид таким образом img = self.__user['avatar'].tobytes(), я на этом моменте долго топтался
Спасибо тебе, добрый человек!
Большое спасибо. ps Аватарки у вас симпатичные
Спасибо огромное за уроки!! У меня вопросик, подскажите... если работать с js и ajax, т.е. чтобы не перегружать страницу, как это можно сделать и как быть с передачей результата SQL запроса в шаблон?
Спасибо вам за огромный вклад. Помните пожалуйста можно ли данный пример (сайт блог) залить на хостинг и использовать бд скюлайт и flask? Или это невозможно? Где это можно тогда применить и как реализовать сайт на питоне с бд?
Как пример, хостинг foxit.com позволяет использовать Flask в качестве бэкэенда. Достаточно написать в службу поддержки, вам все конкретно разьяснят.
Спасибо!
а не проще ли сделать поле аватаркой в бд путем к картинке, картинки грузить в файловую систему, и при создании пользователя применять дефолтный линк ‘/images/default.png’? а когда пользователь загрузит новый аватар, положить его в папку ‘images/users/1.png’, и в базе прописать путь к нему? а в шаблон отдавать путь к картинке. во-первых база будет меньше напрягаться(передать бинарник != передать строку), во-вторых, тем самым, если у нас будет 500 пользователей, будет всего 1 картинка, к которой они все будут ссылаться. в какой-то мере DRY
плюс, насколько я знаю, хранить бинарные файлы в базе данных - плохая практика.
это лишь мое предложение. спасибо вам за ваши труды. очень доступно объясняете.
Спасибо, хороший вопрос. Лично я так и делаю в сайтах - через путь к файлу. Но если это всего лишь небольшая по объему аватарка, которая уникальна для каждого пользователя, то можно и в БД засунуть. И плюс, я хотел показать как вообще картинки можно сохранять и читать из БД на конкретном примере.
Отличный комментарий. У меня вопрос: если реализовать все Вами выше указанное, то как удалять фотографии старых аватаров в папке /image/users?
@@artemkhmil можно написать скрипт, который будет запускаться раз в месяц, и проходиться по всем файлам в папке, и, если файла нет в бд, - удалять его. вообще не проблема. куда лучшее решение, чем хранить миллион одинаковых бинарников в бд)
@@selfedu_rus Вот зря! Не надо учить людей изобретать велосипеды!
Очень странные баги у себя отлавливаю - не грузится свой аватар. Дважды пересмотрел ролик перепроверил каждую строчку написанного кода. Взял ваш profile.html и вставил вместо своего, всё заработало. Из отличий только то, что в {{url_for('upload')}} и {{url_for('logout')}} между двойными фигурными скобками у меня были пробелы (вот так {{ url_for('logout') }}). Из-за этого действительно могло не работать?
Спасибо
Крутооооооо
Вот так вот ребята это делается в самом простом варианте)))
Скажите пожалуйста почему в f-строках сразу нельзя писать обращение к базам данных вставляя переменные в {} кавычки. В прошлых видео встречал в комментах упоминания про SQL инъекции. Видимо это связано с безопасностью. Можете в кратце пояснить или дать наводку, где можно почитать про это) Потому что пока "не бум бум", а узнать хотелось бы. Спасибо =)
Да, сразу не рекомендуется, т.к. в GET-запросе тогда можно будет прописать обращение к БД и сделать нехорошие вещи. Поэтому, нужно в SQLite использовать символы ? - они предотвращают этот момент.
все здорово. Но как это потом в инет то все загрузить?
Привет, учусь по твоим курсам но использую mysql и в коннекторе к python не могу найти такую функцию Binary как у тебя в sqlite. Может есть возможность прочитать загруженный файл сразу в бинарный код используя какой-то другой способ?
Бинарный файл иначе загружать получится только извратом, лучше разобраться, почему нет такой функции. Она стандартная пакета sqlite3. Вначале должен идти импорт (import sqlite3), а затем, обращение к этой функции. Посмотрите, есть ли этот импорт в файле и второе, попробуйте поставить последнюю версию sqlite3.
Я использую mysql вместо sqlite3) В общем сделал немного по другому. У файла, который получаем из объекта запроса есть метод save, который позволяет сохранить этот файл на компе(сервере). В общем благодаря этому методу сохраняю загруженный файл, а потом читаю его в бинарном режиме и отправлю в БД(mysql) уже в бинарном виде. Правда не знаю насколько это хорошая практика, ведь теперь файл сохранён и там и там и по идеи используется больше места. Думаю прикрутить автоматическое удаление с компа после добавления в БД с использованием потока) Получится такой маленький буфер))
P.s Мне кажется я написал это для себя, что бы лучше въехать в то, что я нагородил у себя в коде. И спасибо за уроки!!
Спасибо за ролик!
Вот только не понял зачем отдельно делать "открыть файл", а потом "загрузить". Не лучше ли сделать "изменить аватар", и всё выполнить одной операцией - открыть файл и загрузить?
P.S.
Ещё нарвался на проверку, что имя пользователя должно быть больше 4 (четырёх) символов
...
len(request.form['name']) > 4 and len(request.form['email']) > 4
...
🤦♂.
Ввожу имя "Иван", а регистрация не проходит 😁
Так ведь "Иван" содержит 4 символа. А по условию проверки должно быть больше 4.
Почему для загрузки фото профиля нужен обработчик? Почему нельзя просто загрузить фото из БД, как имя или почту?
Насколько я помню, там нужно еще загружать графический файл на сервер, за это обработчик и отвечает.
Зачем вы удаляете таблицу, вместо того чтобы модифицировать?
Мне тоже интересно как быть, когда сайт уже работает и понадобилось что-то добавить в базу. Не удалять же.
@@AnnaIsHere есть дополнительная библиотека Flask_Migrate как раз для подобных вещей
Еще бы урок по скачиванию файлов из веб-приложения на Flask...
Автор про константу 3 минуты рассказывал, а функции пролетел как будто переменные какие-то.
4-20 лайков. не буду портить, оставлю коммент просто
не нашел класс profile-table в css
под видео есть ссылка на проект занятия
@@selfedu_rus profile-table нету даже там. видимо поэтому у меня не отображает аватар
@@selfedu_rus обидно, поскольку я прошел 17 уроков
@@selfedu_rus если запустить ваш исходник, то аватар не отображается
@@nazarkhort4362 Скорее всего в файле UserLogin.py в функции getAvatar() у Вас в конце нет оператора return img
в css тоже не нашел класса profile-table. поэтому написал сам
.profile-table img, .profile-table svg {
width: 150px;
height: 150px;
top: 20%;
left: 50%;
margin: -12px 0 0 -12px;
}
Автор понимаю бесплатно и тп, но посмотри англоязычные курсы там авторы все-таки более последовательно далеют подачу материала. Здесь как-то нарубил куски и вот держи.
Кто например? Подача немного трудная, согласен