如何使用 flask(使用引导程序)和 python 列出目录的文件?
How to list files of a directory with flask (using bootstraps) and python?
这是我在这个论坛上提出的第一个问题。我非常渴望找到解决方案......希望我能向你们学习。
我有一个解决方案,但是在浏览器中发布整个目录树window 并知道文件名,这不是我想要的。
现在我找到了这样的代码片段并稍微修改了一下。它的生成器表达式,我认为 Jinja2 不支持它:
import os
path = r"C:/Users/add706/Documents/NRL_webseite/website/static/uploads"
def get_files(path):
for file in os.listdir(path):
if os.path.isfile(os.path.join(path, file)):
yield file
for file in get_files(path):
print(file)
输出在路径中给出了 3 个文件:
1.jpeg
postgre.jpeg
winrar-x64-610d.exe
我正在尝试制作一个列表并将其传递给 JINJA2。我已经创建了一个模板,但不知何故,当我 运行 flask 时,我无法列出文件并且打印功能为空。自从我坐在上面 3 天以来,甚至没有错误消息,这可能对我有帮助。
这是我对 auth.py 的原始摘录(库的导入很好,这里没有列出):
path = r"C:/Users/add706/Documents/NRL_webseite/website/static/uploads"
@auth.route('/', methods = ['GET', 'POST'])
def get_files(path):
for file in os.listdir(path):
if os.path.isfile(os.path.join(path, file)):
return (os.listdir(path))
files=[]
for file in get_files(path):
files.append(file)
print(files)
return render_template('home.html', files=get_files(path))
这是我对 home.html 模板(已扩展 %)的原始提取,循环遍历返回的文件(我希望...):
<!-- download Folder-->
<div align="center">
<image src="{{ url_for('static', filename='uploads/postgre.jpeg')}}">
</ul>
{% for file in files %}
<li class="collection-item"><a href="#">{{ file }}</a></li>
{% endfor %}
</ul>
</div>
现在的问题是:我必须在我的两个文件中更改什么才能在我的本地网页 (http://127.0.0.1:5000/) 上看到这 3 个文件?我想列出它们并使它们可点击,因此在点击时,文件可以作为附件下载。第二件事是,将它们与上传时间一起列出。第三件事是,在下载过程中,弹出一个 window,它问我“你想下载(文件名)吗?为了形象化我的问题,我上传了一张图片并画了红框。谢谢你那里的每个帮助。
图片link:(https://imgur.com/a/z4l8zH2)
我找到了这篇文章,它在我的脚本中说树是未定义的(List files in directories with flask),所以我放弃了。
你确实可以在 jinja2 中使用生成器。
我写的例子应该能满足你的需求。
它将目录中的文件显示为列表。每个条目都指定了它的大小和上传时间。上传文件夹位于 instance folder 内,用于将文件与应用程序分开。
我使用 flask-moment to show the correct times. This uses moment.js 并显示客户端各自时区的时间戳。
我使用自定义 Jinja2 filter 来显示文件大小。
如果单击文件进行下载,则会打开一个要求确认的对话框。这是使用 JavaScript.
完成的
享受实现目标的乐趣。
烧瓶 (app.py)
from flask import (
Flask,
render_template,
send_from_directory
)
from flask_moment import Moment
from datetime import datetime
import os
def byte_units(value, units=-1):
UNITS=('Bytes', 'KB', 'MB', 'GB', 'TB', 'EB', 'ZB', 'YB')
i=1
value /= 1000.0
while value > 1000 and (units == -1 or i < units) and i+1 < len(UNITS):
value /= 1000.0
i += 1
return f'{round(value,3):.3f} {UNITS[i]}'
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = os.path.join(app.instance_path, 'uploads')
app.jinja_env.filters.update(byte_units = byte_units)
moment = Moment(app)
try:
os.makedirs(app.config['UPLOAD_FOLDER'])
except:
pass
def get_files(target):
for file in os.listdir(target):
path = os.path.join(target, file)
if os.path.isfile(path):
yield (
file,
datetime.utcfromtimestamp(os.path.getmtime(path)),
os.path.getsize(path)
)
@app.route('/')
def index():
files = get_files(app.config['UPLOAD_FOLDER'])
return render_template('index.html', **locals())
@app.route('/download/<path:filename>')
def download(filename):
return send_from_directory(
app.config['UPLOAD_FOLDER'],
filename,
as_attachment=True
)
HTML (templates/index.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Index</title>
{{ moment.include_moment() }}
</head>
<body>
<table style="width:40%; margin:auto; table-layout: fixed;">
{% for filename, mtime, size in files -%}
<tr>
<td><a href="{{ url_for('download', filename=filename) }}" download>{{ filename }}</a></td>
<td>{{ moment(mtime, local=False).format('DD.MM.YYYY HH:mm') }}</td>
<td style="text-align:right;">{{ size | byte_units }}</td>
</tr>
{% endfor -%}
</table>
<script type="text/javascript">
(() => {
const elems = document.querySelectorAll('a[href][download]');
elems.forEach(elem => {
elem.addEventListener('click', evt => {
const isDonwload = window.confirm('Would you like to download this file?');
if (!isDonwload) { evt.preventDefault(); }
});
});
})();
</script>
</body>
</html>
我已将我的代码添加到您的项目中。它现在应该可以工作了。
您应该努力构建您的项目,以便您可以更轻松地找到解决代码的方法。在这种情况下我不能解除你的任务。
(网站/init.py)
from flask import Flask
from flask_login import LoginManager
from flask_moment import Moment
from flask_sqlalchemy import SQLAlchemy
import os
DB_NAME = "database.db"
db = SQLAlchemy()
moment = Moment()
def byte_units(value, units=-1):
UNITS=('Bytes', 'KB', 'MB', 'GB', 'TB', 'EB', 'ZB', 'YB')
i=1
value /= 1000.0
while value > 1000 and (units == -1 or i < units) and i+1 < len(UNITS):
value /= 1000.0
i += 1
return f'{round(value,3):.3f} {UNITS[i]}'
def create_app():
app = Flask(__name__)
app.config.from_mapping(
SECRET_KEY=b'your secret here',
SQLALCHEMY_DATABASE_URI='sqlite:///'+os.path.join(app.instance_path, DB_NAME),
SQLALCHEMY_TRACK_MODIFICATIONS=False,
UPLOAD_FOLDER=os.path.join(app.instance_path, 'uploads')
)
app.jinja_env.filters.update(byte_units = byte_units)
try:
os.makedirs(app.config['UPLOAD_FOLDER'])
except:
pass
db.init_app(app)
moment.init_app(app)
from .models import User, Note
create_database(app)
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
@login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
from .views import views
from .auth import auth
app.register_blueprint(auth, url_prefix='/')
app.register_blueprint(views, url_prefix='/')
return app
def create_database(app):
if not os.path.exists(os.path.join(app.instance_path, DB_NAME)):
db.create_all(app=app)
print('Created Database!')
(website/auth.py)
import os
import json
from . import db
from .models import User
from flask import (
Blueprint,
flash,
redirect,
render_template,
request,
url_for
)
from flask_login import login_user, login_required, logout_user, current_user
auth = Blueprint('auth', __name__)
@auth.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
email = request.form.get('email')
password = request.form.get('password')
user = User.query.filter_by(email=email).first()
if user:
if check_password_hash(user.password, password):
flash('Logged in successfully!', category='success')
login_user(user, remember=True)
return redirect(url_for('views.home'))
else:
flash('Incorrect password, try again.', category='error')
else:
flash('Email does not exist.', category='error')
return render_template('login.html', user=current_user)
@auth.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('auth.login'))
@auth.route('/sign-up', methods=['GET', 'POST'])
def sign_up():
if request.method == 'POST':
email = request.form.get('email')
first_name = request.form.get('firstName')
password1 = request.form.get('password1')
password2 = request.form.get('password2')
user = User.query.filter_by(email=email).first()
if user:
flash('Email already exists.', category='error')
elif len(email) < 4:
flash('Email must be greater than 3 characters.', category='error')
elif len(first_name) < 2:
flash('First name must be greater than 1 character.', category='error')
elif password1 != password2:
flash('Passwords don\'t match.', category='error')
elif len(password1) < 7:
flash('Password must be at least 7 characters.', category='error')
else:
new_user = User(email=email, first_name=first_name, password=generate_password_hash(
password1, method='sha256'))
db.session.add(new_user)
db.session.commit()
login_user(new_user, remember=True)
flash('Account created!', category='success')
return redirect(url_for('views.home'))
return render_template('sign_up.html', user=current_user)
(website/views.py)
from . import db
from .models import Note
from flask import Blueprint, current_app, flash, jsonify, render_template, request
from flask_login import login_required, current_user
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash
from werkzeug.utils import secure_filename
import os
views = Blueprint('views', __name__)
@views.route('/', methods=['GET', 'POST'])
@login_required
def home():
if request.method == 'POST':
note = request.form.get('note')
if len(note) < 1:
flash('Note is too short!', category='error')
else:
new_note = Note(data=note, user_id=current_user.id)
db.session.add(new_note)
db.session.commit()
flash('Note added!', category='success')
user=current_user
files = get_files(current_app.config['UPLOAD_FOLDER'])
return render_template('home.html', **locals())
@views.route('/delete-note', methods=['POST'])
def delete_note():
note = json.loads(request.data)
noteId = note['noteId']
note = Note.query.get(noteId)
if note:
if note.user_id == current_user.id:
db.session.delete(note)
db.session.commit()
return jsonify({})
# ---
@views.route('/about')
def about():
return render_template('about.html', user=None)
# ---
@views.route('/upload', methods = ['GET', 'POST'])
def uploadfile():
upload_folder = current_app.config['UPLOAD_FOLDER']
if request.method == 'POST': # check if the method is post
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file'] # get the file from the files object
if file.filename == '':
flash('No selected file')
return redirect(request.url)
file.save(os.path.join(
upload_folder ,
secure_filename(file.filename))) # this will secure the file
flash('file uploaded successfully') # Display this message after uploading
return redirect('/')
def get_files(target):
for file in os.listdir(target):
path = os.path.join(target, file)
if os.path.isfile(path):
yield (
file,
datetime.utcfromtimestamp(os.path.getmtime(path)),
os.path.getsize(path)
)
@views.route('/download/<path:filename>')
def download(filename):
return send_from_directory(
app.config['UPLOAD_FOLDER'],
filename,
as_attachment=True
)
(templates/base.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
crossorigin="anonymous"
/>
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
crossorigin="anonymous"
/>
<title>{% block title %}Home{% endblock %}</title>
{{ moment.include_moment() }}
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<button
class="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbar"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbar">
<div class="navbar-nav">
{% if user.is_authenticated %}
<a class="nav-item nav-link" id="home" href="/">Home</a>
<a class="nav-item nav-link" id="logout" href="/logout">Logout</a>
{% else %}
<a class="nav-item nav-link" id="login" href="/login">Login</a>
<a class="nav-item nav-link" id="signUp" href="/sign-up">Sign Up</a>
<a class="nav-item nav-link" id="Über Uns" href="/about">Über uns</a>
{% endif %}
</div>
</div>
</nav>
{% with messages = get_flashed_messages(with_categories=true) %} {% if
messages %} {% for category, message in messages %} {% if category ==
'error' %}
<div class="alert alert-danger alter-dismissable fade show" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert">
<span aria-hidden="true">×</span>
</button>
</div>
{% else %}
<div class="alert alert-success alter-dismissable fade show" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert">
<span aria-hidden="true">×</span>
</button>
</div>
{% endif %} {% endfor %} {% endif %} {% endwith %}
<div class="container">{% block content %} {% endblock %}</div>
<script
src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"
></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"
></script>
<script
type="text/javascript"
src="{{ url_for('static', filename='index.js') }}"
></script>
</body>
</html>
(templates/home.html)
{% extends "base.html" -%}
{% block title %}Home{% endblock -%}
{% block content -%}
<h1 align="center">Notes</h1>
<ul class="list-group list-group-flush" id="notes">
{% for note in user.notes %}
<li class="list-group-item">
{{ note.data }}
<button type="button" class="close" onClick="deleteNote({{ note.id }})">
<span aria-hidden="true">×</span>
</button>
</li>
{% endfor %}
</ul>
<form method="POST">
<textarea name="note" id="note" class="form-control"></textarea>
<br />
<div align="center">
<button type="submit" class="btn btn-primary">Add Note</button>
</div>
</form>
<br>
<br>
<br>
<br>
<!-- upload Folder-->
<div class="container">
<div class="row">
<div class="col">
<h1 align="center">Datei Upload</h1>
<hr>
<form
action="http://localhost:5000/upload"
method="POST"
enctype="multipart/form-data">
<input type="file" name="file" />
<button type="submit" class="btn btn-primary">Upload</button>
</form>
</div>
</div>
</div>
<br>
<br>
<br>
<br>
<!-- download Folder-->
<div align="center">
<image src="{{ url_for('static', filename='uploads/postgre.jpeg')}}">
</div>
<table style="width:40%; margin:auto; table-layout: fixed;">
{% for filename, mtime, size in files -%}
<tr>
<td><a href="{{ url_for('views.download', filename=filename) }}" download>{{ filename }}</a></td>
<td>{{ moment(mtime, local=False).format('DD.MM.YYYY HH:mm') }}</td>
<td style="text-align:right;">{{ size | byte_units }}</td>
</tr>
{% endfor -%}
</table>
<script type="text/javascript">
(() => {
const elems = document.querySelectorAll('a[href][download]');
elems.forEach(elem => {
elem.addEventListener('click', evt => {
const isDonwload = window.confirm('Would you like to download this file?');
if (!isDonwload) { evt.preventDefault(); }
});
});
})();
</script>
{% endblock -%}
在@Detlef 的帮助下,创建了一个本地网络服务器,您可以使用它登录、注册和留言。然后设置了上传和下载选项。
我从树结构开始。
C:.
| main.py
| output.doc
|
+---instance
| | database.db
| |
| \---uploads
| postgre.jpeg
| project.jpg
|
+---website
| | auth.py
| | database.db
| | models.py
| | output.doc
| | views.py
| | __init__.py
| |
| +---static
| | | index.js
| | |
| | \---Bilder
| | sun.jpg
| | logo.png
| | postgre.jpeg
| |
| +---templates
| | about.html
| | base.html
| | home.html
| | login.html
| | sign_up.html
| |
| \---__pycache__
| app.cpython-39.pyc
| auth.cpython-39.pyc
| download.cpython-39.pyc
| models.cpython-39.pyc
| views.cpython-39.pyc
| __init__.cpython-39.pyc
|
从 main.py 开始:
from website import create_app # website folder
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
这是auth.py:
from . import db
from werkzeug.security import generate_password_hash, check_password_hash
from .models import User
from flask import (
Blueprint,
flash,
redirect,
render_template,
request,
url_for
)
from flask_login import login_user, login_required, logout_user, current_user
auth = Blueprint('auth', __name__)
@auth.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
email = request.form.get('email')
password = request.form.get('password')
user = User.query.filter_by(email=email).first()
if user:
if check_password_hash(user.password, password):
flash('Logged in successfully!', category='success')
login_user(user, remember=True)
return redirect(url_for('views.home'))
else:
flash('Incorrect password, try again.', category='error')
else:
flash('Email does not exist.', category='error')
return render_template('login.html', user=current_user)
@auth.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('auth.login'))
@auth.route('/sign-up', methods=['GET', 'POST'])
def sign_up():
if request.method == 'POST':
email = request.form.get('email')
first_name = request.form.get('firstName')
password1 = request.form.get('password1')
password2 = request.form.get('password2')
user = User.query.filter_by(email=email).first()
if user:
flash('Email already exists.', category='error')
elif len(email) < 4:
flash('Email must be greater than 3 characters.', category='error')
elif len(first_name) < 2:
flash('First name must be greater than 1 character.', category='error')
elif password1 != password2:
flash('Passwords don\'t match.', category='error')
elif len(password1) < 7:
flash('Password must be at least 7 characters.', category='error')
else:
new_user = User(email=email, first_name=first_name, password=generate_password_hash(
password1, method='sha256'))
db.session.add(new_user)
db.session.commit()
login_user(new_user, remember=True)
flash('Account created!', category='success')
return redirect(url_for('views.home'))
return render_template('sign_up.html', user=current_user)
这是views.py:
from . import db
from .models import Note
from flask import Blueprint, render_template, request, flash, redirect, url_for, send_from_directory, abort, jsonify
from flask_login import login_required, current_user
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash
from werkzeug.utils import secure_filename
import os
import json
from flask_moment import Moment
from flask import Flask
views = Blueprint('views', __name__)
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = os.path.join(app.instance_path, '/uploads')
moment = Moment(app)
@views.route('/', methods=['GET', 'POST'])
@login_required
def home():
if request.method == 'POST':
note = request.form.get('note')
if len(note) < 1:
flash('Note is too short!', category='error')
else:
new_note = Note(data=note, user_id=current_user.id)
db.session.add(new_note)
db.session.commit()
flash('Note added!', category='success')
user=current_user
files = get_files(app.config['UPLOAD_FOLDER'])
return render_template('home.html', **locals())
@views.route('/delete-note', methods=['POST'])
def delete_note():
note = json.loads(request.data)
noteId = note['noteId']
note = Note.query.get(noteId)
if note:
if note.user_id == current_user.id:
db.session.delete(note)
db.session.commit()
return jsonify({})
# ---
@views.route('/about')
def about():
return render_template('about.html', user=None)
# ---
@views.route('/upload', methods = ['GET', 'POST'])
def uploadfile():
upload_folder = app.config['UPLOAD_FOLDER']
if request.method == 'POST': # check if the method is post
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file'] # get the file from the files object
if file.filename == '':
flash('No selected file')
return redirect(request.url)
file.save(os.path.join(
upload_folder ,
secure_filename(file.filename))) # this will secure the file
flash('file uploaded successfully') # Display this message after uploading
return redirect('/')
def get_files(target):
for file in os.listdir(target):
path = os.path.join(target, file)
if os.path.isfile(path):
yield (
file,
datetime.utcfromtimestamp(os.path.getmtime(path)),
os.path.getsize(path)
)
@views.route('/download/<path:filename>')
def download(filename):
return send_from_directory(
app.config['UPLOAD_FOLDER'],
filename,
as_attachment=True
)
这是init.py:
from flask import Flask
from flask_login import LoginManager
from flask_moment import Moment
from flask_sqlalchemy import SQLAlchemy
import os
DB_NAME = "database.db"
db = SQLAlchemy()
moment = Moment()
def byte_units(value, units=-1):
UNITS=('Bytes', 'KB', 'MB', 'GB', 'TB', 'EB', 'ZB', 'YB')
i=1
value /= 1000.0
while value > 1000 and (units == -1 or i < units) and i+1 < len(UNITS):
value /= 1000.0
i += 1
return f'{round(value,3):.3f} {UNITS[i]}'
def create_app():
app = Flask(__name__)
app.config.from_mapping(
SECRET_KEY=b'your secret here',
SQLALCHEMY_DATABASE_URI='sqlite:///'+os.path.join(app.instance_path, DB_NAME),
SQLALCHEMY_TRACK_MODIFICATIONS=False,
UPLOAD_FOLDER=os.path.join(app.instance_path, 'uploads')
)
app.jinja_env.filters.update(byte_units = byte_units)
try:
os.makedirs(app.config['UPLOAD_FOLDER'])
except:
pass
db.init_app(app)
moment.init_app(app)
from .models import User, Note
create_database(app)
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
@login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
from .views import views
from .auth import auth
app.register_blueprint(auth, url_prefix='/')
app.register_blueprint(views, url_prefix='/')
return app
def create_database(app):
if not os.path.exists(os.path.join(app.instance_path, DB_NAME)):
db.create_all(app=app)
print('Created Database!')
这是models.py:
from . import db
from flask_login import UserMixin
from sqlalchemy.sql import func
class Note(db.Model):
id = db.Column(db.Integer, primary_key=True)
data = db.Column(db.String(10000))
date = db.Column(db.DateTime(timezone=True), default=func.now())
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(150), unique=True)
password = db.Column(db.String(150))
first_name = db.Column(db.String(150))
notes = db.relationship('Note')
这是 home.html 模板:
{% extends "base.html" -%}
{% block title %}Home{% endblock -%}
{% block content -%}
<h1 align="center">Notes</h1>
<ul class="list-group list-group-flush" id="notes">
{% for note in user.notes %}
<li class="list-group-item">
{{ note.data }}
<button type="button" class="close" onClick="deleteNote({{ note.id }})">
<span aria-hidden="true">×</span>
</button>
</li>
{% endfor %}
</ul>
<form method="POST">
<textarea name="note" id="note" class="form-control"></textarea>
<br />
<div align="center">
<button type="submit" class="btn btn-primary">Add Note</button>
</div>
</form>
<br>
<br>
<br>
<br>
<!-- upload Folder-->
<div class="container">
<div class="row">
<div class="col">
<h1 align="center">Datei Upload</h1>
<hr>
<form
action="http://localhost:5000/upload"
method="POST"
enctype="multipart/form-data">
<input type="file" name="file" />
<button type="submit" class="btn btn-primary">Upload</button>
</form>
</div>
</div>
</div>
<br>
<br>
<br>
<br>
<!-- download Folder-->
<div align="center">
<image src="{{ url_for('static', filename='Bilder/postgre.jpeg')}}">
</div>
<head>
<style>
table, th, td {
border: 1px solid black;
}
</style>
</head>
<body>
<h1>Downloads</h1>
<table style="width:100%; margin:auto; table-layout: fixed;">
{% for filename, mtime, size in files -%}
<tr>
<th>Dateiname</th>
<th>Datum und Uhrzeit</th>
<th>Dateigröße</th>
</tr>
<tr>
<td><a href="{{ url_for('views.download', filename=filename) }}" download>{{ filename }}</a></td>
<td>{{ moment(mtime, local=False).format('DD.MM.YYYY HH:mm') }}</td>
<td style="text-align:right;">{{ size | byte_units }}</td>
</tr>
{% endfor -%}
</table>
<script type="text/javascript">
(() => {
const elems = document.querySelectorAll('a[href][download]');
elems.forEach(elem => {
elem.addEventListener('click', evt => {
const isDonwload = window.confirm('Möchten Sie die ausgewählte Datei herunterladen??');
if (!isDonwload) { evt.preventDefault(); }
});
});
})();
</script>
{% endblock -%}
这是login.hmtl
{% extends "base.html" %} {% block title %}Login{% endblock %} {% block content
%}
<form method="POST">
<h3 align="center">Login</h3>
<div class="form-group">
<label for="email">Email Addresse</label>
<input
type="email"
class="form-control"
id="email"
name="email"
placeholder="Email Eingabe"
/>
</div>
<div class="form-group">
<label for="password">Passwort</label>
<input
type="password"
class="form-control"
id="password"
name="password"
placeholder="Passwort Eingabe"
/>
</div>
<br />
<button type="submit" class="btn btn-primary">Login</button>
</form>
{% endblock %}
这是sign_up.hmtl
{% extends "base.html" %} {% block title %}Sign Up{% endblock %} {% block
content %}
<body>
<h3 align="center"><img src="{{ url_for('static', filename='Bilder/Logo-NRL-blau.png') }}" alt=""></h3>
</body>
<form method="POST">
<h3 align="center">Sign Up</h3>
<div class="form-group">
<label for="email">Email-Addresse</label>
<input
type="email"
class="form-control"
id="email"
name="email"
placeholder="Email Eingabe"
/>
</div>
<div class="form-group">
<label for="firstName">Vollständiger Name</label>
<input
type="text"
class="form-control"
id="firstName"
name="firstName"
placeholder="Eingabe des vollständigen Namens"
/>
</div>
<div class="form-group">
<label for="password1">Passwort</label>
<input
type="password"
class="form-control"
id="password1"
name="password1"
placeholder="Passwort Eingabe"
/>
</div>
<div class="form-group">
<label for="password2">Passwort (Wiederholung)</label>
<input
type="password"
class="form-control"
id="password2"
name="password2"
placeholder="Passwort (Bestätigung)"
/>
</div>
<br />
<button type="submit" class="btn btn-primary">Submit</button>
</form>
{% endblock %}
这是base.hmtl
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
crossorigin="anonymous"
/>
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
crossorigin="anonymous"
/>
<title>{% block title %}Home{% endblock %}</title>
{{ moment.include_moment() }}
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<button
class="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbar"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbar">
<div class="navbar-nav">
{% if user.is_authenticated %}
<a class="nav-item nav-link" id="home" href="/">Home</a>
<a class="nav-item nav-link" id="logout" href="/logout">Logout</a>
{% else %}
<a class="nav-item nav-link" id="login" href="/login">Login</a>
<a class="nav-item nav-link" id="signUp" href="/sign-up">Sign Up</a>
<a class="nav-item nav-link" id="Über Uns" href="/about">Über uns</a>
{% endif %}
</div>
</div>
</nav>
{% with messages = get_flashed_messages(with_categories=true) %} {% if
messages %} {% for category, message in messages %} {% if category ==
'error' %}
<div class="alert alert-danger alter-dismissable fade show" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert">
<span aria-hidden="true">×</span>
</button>
</div>
{% else %}
<div class="alert alert-success alter-dismissable fade show" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert">
<span aria-hidden="true">×</span>
</button>
</div>
{% endif %} {% endfor %} {% endif %} {% endwith %}
<div class="container">{% block content %} {% endblock %}</div>
<script
src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"
></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"
></script>
<script
type="text/javascript"
src="{{ url_for('static', filename='index.js') }}"
></script>
</body>
</html>
玩得开心。并感谢@Detlef !!!!!!!
这是我在这个论坛上提出的第一个问题。我非常渴望找到解决方案......希望我能向你们学习。 我有一个解决方案,但是在浏览器中发布整个目录树window 并知道文件名,这不是我想要的。
现在我找到了这样的代码片段并稍微修改了一下。它的生成器表达式,我认为 Jinja2 不支持它:
import os
path = r"C:/Users/add706/Documents/NRL_webseite/website/static/uploads"
def get_files(path):
for file in os.listdir(path):
if os.path.isfile(os.path.join(path, file)):
yield file
for file in get_files(path):
print(file)
输出在路径中给出了 3 个文件: 1.jpeg postgre.jpeg winrar-x64-610d.exe
我正在尝试制作一个列表并将其传递给 JINJA2。我已经创建了一个模板,但不知何故,当我 运行 flask 时,我无法列出文件并且打印功能为空。自从我坐在上面 3 天以来,甚至没有错误消息,这可能对我有帮助。
这是我对 auth.py 的原始摘录(库的导入很好,这里没有列出):
path = r"C:/Users/add706/Documents/NRL_webseite/website/static/uploads"
@auth.route('/', methods = ['GET', 'POST'])
def get_files(path):
for file in os.listdir(path):
if os.path.isfile(os.path.join(path, file)):
return (os.listdir(path))
files=[]
for file in get_files(path):
files.append(file)
print(files)
return render_template('home.html', files=get_files(path))
这是我对 home.html 模板(已扩展 %)的原始提取,循环遍历返回的文件(我希望...):
<!-- download Folder-->
<div align="center">
<image src="{{ url_for('static', filename='uploads/postgre.jpeg')}}">
</ul>
{% for file in files %}
<li class="collection-item"><a href="#">{{ file }}</a></li>
{% endfor %}
</ul>
</div>
现在的问题是:我必须在我的两个文件中更改什么才能在我的本地网页 (http://127.0.0.1:5000/) 上看到这 3 个文件?我想列出它们并使它们可点击,因此在点击时,文件可以作为附件下载。第二件事是,将它们与上传时间一起列出。第三件事是,在下载过程中,弹出一个 window,它问我“你想下载(文件名)吗?为了形象化我的问题,我上传了一张图片并画了红框。谢谢你那里的每个帮助。
图片link:(https://imgur.com/a/z4l8zH2)
我找到了这篇文章,它在我的脚本中说树是未定义的(List files in directories with flask),所以我放弃了。
你确实可以在 jinja2 中使用生成器。
我写的例子应该能满足你的需求。
它将目录中的文件显示为列表。每个条目都指定了它的大小和上传时间。上传文件夹位于 instance folder 内,用于将文件与应用程序分开。
我使用 flask-moment to show the correct times. This uses moment.js 并显示客户端各自时区的时间戳。
我使用自定义 Jinja2 filter 来显示文件大小。
如果单击文件进行下载,则会打开一个要求确认的对话框。这是使用 JavaScript.
完成的
享受实现目标的乐趣。
烧瓶 (app.py)
from flask import (
Flask,
render_template,
send_from_directory
)
from flask_moment import Moment
from datetime import datetime
import os
def byte_units(value, units=-1):
UNITS=('Bytes', 'KB', 'MB', 'GB', 'TB', 'EB', 'ZB', 'YB')
i=1
value /= 1000.0
while value > 1000 and (units == -1 or i < units) and i+1 < len(UNITS):
value /= 1000.0
i += 1
return f'{round(value,3):.3f} {UNITS[i]}'
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = os.path.join(app.instance_path, 'uploads')
app.jinja_env.filters.update(byte_units = byte_units)
moment = Moment(app)
try:
os.makedirs(app.config['UPLOAD_FOLDER'])
except:
pass
def get_files(target):
for file in os.listdir(target):
path = os.path.join(target, file)
if os.path.isfile(path):
yield (
file,
datetime.utcfromtimestamp(os.path.getmtime(path)),
os.path.getsize(path)
)
@app.route('/')
def index():
files = get_files(app.config['UPLOAD_FOLDER'])
return render_template('index.html', **locals())
@app.route('/download/<path:filename>')
def download(filename):
return send_from_directory(
app.config['UPLOAD_FOLDER'],
filename,
as_attachment=True
)
HTML (templates/index.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Index</title>
{{ moment.include_moment() }}
</head>
<body>
<table style="width:40%; margin:auto; table-layout: fixed;">
{% for filename, mtime, size in files -%}
<tr>
<td><a href="{{ url_for('download', filename=filename) }}" download>{{ filename }}</a></td>
<td>{{ moment(mtime, local=False).format('DD.MM.YYYY HH:mm') }}</td>
<td style="text-align:right;">{{ size | byte_units }}</td>
</tr>
{% endfor -%}
</table>
<script type="text/javascript">
(() => {
const elems = document.querySelectorAll('a[href][download]');
elems.forEach(elem => {
elem.addEventListener('click', evt => {
const isDonwload = window.confirm('Would you like to download this file?');
if (!isDonwload) { evt.preventDefault(); }
});
});
})();
</script>
</body>
</html>
我已将我的代码添加到您的项目中。它现在应该可以工作了。
您应该努力构建您的项目,以便您可以更轻松地找到解决代码的方法。在这种情况下我不能解除你的任务。
(网站/init.py)
from flask import Flask
from flask_login import LoginManager
from flask_moment import Moment
from flask_sqlalchemy import SQLAlchemy
import os
DB_NAME = "database.db"
db = SQLAlchemy()
moment = Moment()
def byte_units(value, units=-1):
UNITS=('Bytes', 'KB', 'MB', 'GB', 'TB', 'EB', 'ZB', 'YB')
i=1
value /= 1000.0
while value > 1000 and (units == -1 or i < units) and i+1 < len(UNITS):
value /= 1000.0
i += 1
return f'{round(value,3):.3f} {UNITS[i]}'
def create_app():
app = Flask(__name__)
app.config.from_mapping(
SECRET_KEY=b'your secret here',
SQLALCHEMY_DATABASE_URI='sqlite:///'+os.path.join(app.instance_path, DB_NAME),
SQLALCHEMY_TRACK_MODIFICATIONS=False,
UPLOAD_FOLDER=os.path.join(app.instance_path, 'uploads')
)
app.jinja_env.filters.update(byte_units = byte_units)
try:
os.makedirs(app.config['UPLOAD_FOLDER'])
except:
pass
db.init_app(app)
moment.init_app(app)
from .models import User, Note
create_database(app)
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
@login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
from .views import views
from .auth import auth
app.register_blueprint(auth, url_prefix='/')
app.register_blueprint(views, url_prefix='/')
return app
def create_database(app):
if not os.path.exists(os.path.join(app.instance_path, DB_NAME)):
db.create_all(app=app)
print('Created Database!')
(website/auth.py)
import os
import json
from . import db
from .models import User
from flask import (
Blueprint,
flash,
redirect,
render_template,
request,
url_for
)
from flask_login import login_user, login_required, logout_user, current_user
auth = Blueprint('auth', __name__)
@auth.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
email = request.form.get('email')
password = request.form.get('password')
user = User.query.filter_by(email=email).first()
if user:
if check_password_hash(user.password, password):
flash('Logged in successfully!', category='success')
login_user(user, remember=True)
return redirect(url_for('views.home'))
else:
flash('Incorrect password, try again.', category='error')
else:
flash('Email does not exist.', category='error')
return render_template('login.html', user=current_user)
@auth.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('auth.login'))
@auth.route('/sign-up', methods=['GET', 'POST'])
def sign_up():
if request.method == 'POST':
email = request.form.get('email')
first_name = request.form.get('firstName')
password1 = request.form.get('password1')
password2 = request.form.get('password2')
user = User.query.filter_by(email=email).first()
if user:
flash('Email already exists.', category='error')
elif len(email) < 4:
flash('Email must be greater than 3 characters.', category='error')
elif len(first_name) < 2:
flash('First name must be greater than 1 character.', category='error')
elif password1 != password2:
flash('Passwords don\'t match.', category='error')
elif len(password1) < 7:
flash('Password must be at least 7 characters.', category='error')
else:
new_user = User(email=email, first_name=first_name, password=generate_password_hash(
password1, method='sha256'))
db.session.add(new_user)
db.session.commit()
login_user(new_user, remember=True)
flash('Account created!', category='success')
return redirect(url_for('views.home'))
return render_template('sign_up.html', user=current_user)
(website/views.py)
from . import db
from .models import Note
from flask import Blueprint, current_app, flash, jsonify, render_template, request
from flask_login import login_required, current_user
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash
from werkzeug.utils import secure_filename
import os
views = Blueprint('views', __name__)
@views.route('/', methods=['GET', 'POST'])
@login_required
def home():
if request.method == 'POST':
note = request.form.get('note')
if len(note) < 1:
flash('Note is too short!', category='error')
else:
new_note = Note(data=note, user_id=current_user.id)
db.session.add(new_note)
db.session.commit()
flash('Note added!', category='success')
user=current_user
files = get_files(current_app.config['UPLOAD_FOLDER'])
return render_template('home.html', **locals())
@views.route('/delete-note', methods=['POST'])
def delete_note():
note = json.loads(request.data)
noteId = note['noteId']
note = Note.query.get(noteId)
if note:
if note.user_id == current_user.id:
db.session.delete(note)
db.session.commit()
return jsonify({})
# ---
@views.route('/about')
def about():
return render_template('about.html', user=None)
# ---
@views.route('/upload', methods = ['GET', 'POST'])
def uploadfile():
upload_folder = current_app.config['UPLOAD_FOLDER']
if request.method == 'POST': # check if the method is post
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file'] # get the file from the files object
if file.filename == '':
flash('No selected file')
return redirect(request.url)
file.save(os.path.join(
upload_folder ,
secure_filename(file.filename))) # this will secure the file
flash('file uploaded successfully') # Display this message after uploading
return redirect('/')
def get_files(target):
for file in os.listdir(target):
path = os.path.join(target, file)
if os.path.isfile(path):
yield (
file,
datetime.utcfromtimestamp(os.path.getmtime(path)),
os.path.getsize(path)
)
@views.route('/download/<path:filename>')
def download(filename):
return send_from_directory(
app.config['UPLOAD_FOLDER'],
filename,
as_attachment=True
)
(templates/base.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
crossorigin="anonymous"
/>
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
crossorigin="anonymous"
/>
<title>{% block title %}Home{% endblock %}</title>
{{ moment.include_moment() }}
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<button
class="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbar"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbar">
<div class="navbar-nav">
{% if user.is_authenticated %}
<a class="nav-item nav-link" id="home" href="/">Home</a>
<a class="nav-item nav-link" id="logout" href="/logout">Logout</a>
{% else %}
<a class="nav-item nav-link" id="login" href="/login">Login</a>
<a class="nav-item nav-link" id="signUp" href="/sign-up">Sign Up</a>
<a class="nav-item nav-link" id="Über Uns" href="/about">Über uns</a>
{% endif %}
</div>
</div>
</nav>
{% with messages = get_flashed_messages(with_categories=true) %} {% if
messages %} {% for category, message in messages %} {% if category ==
'error' %}
<div class="alert alert-danger alter-dismissable fade show" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert">
<span aria-hidden="true">×</span>
</button>
</div>
{% else %}
<div class="alert alert-success alter-dismissable fade show" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert">
<span aria-hidden="true">×</span>
</button>
</div>
{% endif %} {% endfor %} {% endif %} {% endwith %}
<div class="container">{% block content %} {% endblock %}</div>
<script
src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"
></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"
></script>
<script
type="text/javascript"
src="{{ url_for('static', filename='index.js') }}"
></script>
</body>
</html>
(templates/home.html)
{% extends "base.html" -%}
{% block title %}Home{% endblock -%}
{% block content -%}
<h1 align="center">Notes</h1>
<ul class="list-group list-group-flush" id="notes">
{% for note in user.notes %}
<li class="list-group-item">
{{ note.data }}
<button type="button" class="close" onClick="deleteNote({{ note.id }})">
<span aria-hidden="true">×</span>
</button>
</li>
{% endfor %}
</ul>
<form method="POST">
<textarea name="note" id="note" class="form-control"></textarea>
<br />
<div align="center">
<button type="submit" class="btn btn-primary">Add Note</button>
</div>
</form>
<br>
<br>
<br>
<br>
<!-- upload Folder-->
<div class="container">
<div class="row">
<div class="col">
<h1 align="center">Datei Upload</h1>
<hr>
<form
action="http://localhost:5000/upload"
method="POST"
enctype="multipart/form-data">
<input type="file" name="file" />
<button type="submit" class="btn btn-primary">Upload</button>
</form>
</div>
</div>
</div>
<br>
<br>
<br>
<br>
<!-- download Folder-->
<div align="center">
<image src="{{ url_for('static', filename='uploads/postgre.jpeg')}}">
</div>
<table style="width:40%; margin:auto; table-layout: fixed;">
{% for filename, mtime, size in files -%}
<tr>
<td><a href="{{ url_for('views.download', filename=filename) }}" download>{{ filename }}</a></td>
<td>{{ moment(mtime, local=False).format('DD.MM.YYYY HH:mm') }}</td>
<td style="text-align:right;">{{ size | byte_units }}</td>
</tr>
{% endfor -%}
</table>
<script type="text/javascript">
(() => {
const elems = document.querySelectorAll('a[href][download]');
elems.forEach(elem => {
elem.addEventListener('click', evt => {
const isDonwload = window.confirm('Would you like to download this file?');
if (!isDonwload) { evt.preventDefault(); }
});
});
})();
</script>
{% endblock -%}
在@Detlef 的帮助下,创建了一个本地网络服务器,您可以使用它登录、注册和留言。然后设置了上传和下载选项。
我从树结构开始。
C:.
| main.py
| output.doc
|
+---instance
| | database.db
| |
| \---uploads
| postgre.jpeg
| project.jpg
|
+---website
| | auth.py
| | database.db
| | models.py
| | output.doc
| | views.py
| | __init__.py
| |
| +---static
| | | index.js
| | |
| | \---Bilder
| | sun.jpg
| | logo.png
| | postgre.jpeg
| |
| +---templates
| | about.html
| | base.html
| | home.html
| | login.html
| | sign_up.html
| |
| \---__pycache__
| app.cpython-39.pyc
| auth.cpython-39.pyc
| download.cpython-39.pyc
| models.cpython-39.pyc
| views.cpython-39.pyc
| __init__.cpython-39.pyc
|
从 main.py 开始:
from website import create_app # website folder
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
这是auth.py:
from . import db
from werkzeug.security import generate_password_hash, check_password_hash
from .models import User
from flask import (
Blueprint,
flash,
redirect,
render_template,
request,
url_for
)
from flask_login import login_user, login_required, logout_user, current_user
auth = Blueprint('auth', __name__)
@auth.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
email = request.form.get('email')
password = request.form.get('password')
user = User.query.filter_by(email=email).first()
if user:
if check_password_hash(user.password, password):
flash('Logged in successfully!', category='success')
login_user(user, remember=True)
return redirect(url_for('views.home'))
else:
flash('Incorrect password, try again.', category='error')
else:
flash('Email does not exist.', category='error')
return render_template('login.html', user=current_user)
@auth.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('auth.login'))
@auth.route('/sign-up', methods=['GET', 'POST'])
def sign_up():
if request.method == 'POST':
email = request.form.get('email')
first_name = request.form.get('firstName')
password1 = request.form.get('password1')
password2 = request.form.get('password2')
user = User.query.filter_by(email=email).first()
if user:
flash('Email already exists.', category='error')
elif len(email) < 4:
flash('Email must be greater than 3 characters.', category='error')
elif len(first_name) < 2:
flash('First name must be greater than 1 character.', category='error')
elif password1 != password2:
flash('Passwords don\'t match.', category='error')
elif len(password1) < 7:
flash('Password must be at least 7 characters.', category='error')
else:
new_user = User(email=email, first_name=first_name, password=generate_password_hash(
password1, method='sha256'))
db.session.add(new_user)
db.session.commit()
login_user(new_user, remember=True)
flash('Account created!', category='success')
return redirect(url_for('views.home'))
return render_template('sign_up.html', user=current_user)
这是views.py:
from . import db
from .models import Note
from flask import Blueprint, render_template, request, flash, redirect, url_for, send_from_directory, abort, jsonify
from flask_login import login_required, current_user
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash
from werkzeug.utils import secure_filename
import os
import json
from flask_moment import Moment
from flask import Flask
views = Blueprint('views', __name__)
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = os.path.join(app.instance_path, '/uploads')
moment = Moment(app)
@views.route('/', methods=['GET', 'POST'])
@login_required
def home():
if request.method == 'POST':
note = request.form.get('note')
if len(note) < 1:
flash('Note is too short!', category='error')
else:
new_note = Note(data=note, user_id=current_user.id)
db.session.add(new_note)
db.session.commit()
flash('Note added!', category='success')
user=current_user
files = get_files(app.config['UPLOAD_FOLDER'])
return render_template('home.html', **locals())
@views.route('/delete-note', methods=['POST'])
def delete_note():
note = json.loads(request.data)
noteId = note['noteId']
note = Note.query.get(noteId)
if note:
if note.user_id == current_user.id:
db.session.delete(note)
db.session.commit()
return jsonify({})
# ---
@views.route('/about')
def about():
return render_template('about.html', user=None)
# ---
@views.route('/upload', methods = ['GET', 'POST'])
def uploadfile():
upload_folder = app.config['UPLOAD_FOLDER']
if request.method == 'POST': # check if the method is post
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file'] # get the file from the files object
if file.filename == '':
flash('No selected file')
return redirect(request.url)
file.save(os.path.join(
upload_folder ,
secure_filename(file.filename))) # this will secure the file
flash('file uploaded successfully') # Display this message after uploading
return redirect('/')
def get_files(target):
for file in os.listdir(target):
path = os.path.join(target, file)
if os.path.isfile(path):
yield (
file,
datetime.utcfromtimestamp(os.path.getmtime(path)),
os.path.getsize(path)
)
@views.route('/download/<path:filename>')
def download(filename):
return send_from_directory(
app.config['UPLOAD_FOLDER'],
filename,
as_attachment=True
)
这是init.py:
from flask import Flask
from flask_login import LoginManager
from flask_moment import Moment
from flask_sqlalchemy import SQLAlchemy
import os
DB_NAME = "database.db"
db = SQLAlchemy()
moment = Moment()
def byte_units(value, units=-1):
UNITS=('Bytes', 'KB', 'MB', 'GB', 'TB', 'EB', 'ZB', 'YB')
i=1
value /= 1000.0
while value > 1000 and (units == -1 or i < units) and i+1 < len(UNITS):
value /= 1000.0
i += 1
return f'{round(value,3):.3f} {UNITS[i]}'
def create_app():
app = Flask(__name__)
app.config.from_mapping(
SECRET_KEY=b'your secret here',
SQLALCHEMY_DATABASE_URI='sqlite:///'+os.path.join(app.instance_path, DB_NAME),
SQLALCHEMY_TRACK_MODIFICATIONS=False,
UPLOAD_FOLDER=os.path.join(app.instance_path, 'uploads')
)
app.jinja_env.filters.update(byte_units = byte_units)
try:
os.makedirs(app.config['UPLOAD_FOLDER'])
except:
pass
db.init_app(app)
moment.init_app(app)
from .models import User, Note
create_database(app)
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
@login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
from .views import views
from .auth import auth
app.register_blueprint(auth, url_prefix='/')
app.register_blueprint(views, url_prefix='/')
return app
def create_database(app):
if not os.path.exists(os.path.join(app.instance_path, DB_NAME)):
db.create_all(app=app)
print('Created Database!')
这是models.py:
from . import db
from flask_login import UserMixin
from sqlalchemy.sql import func
class Note(db.Model):
id = db.Column(db.Integer, primary_key=True)
data = db.Column(db.String(10000))
date = db.Column(db.DateTime(timezone=True), default=func.now())
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(150), unique=True)
password = db.Column(db.String(150))
first_name = db.Column(db.String(150))
notes = db.relationship('Note')
这是 home.html 模板:
{% extends "base.html" -%}
{% block title %}Home{% endblock -%}
{% block content -%}
<h1 align="center">Notes</h1>
<ul class="list-group list-group-flush" id="notes">
{% for note in user.notes %}
<li class="list-group-item">
{{ note.data }}
<button type="button" class="close" onClick="deleteNote({{ note.id }})">
<span aria-hidden="true">×</span>
</button>
</li>
{% endfor %}
</ul>
<form method="POST">
<textarea name="note" id="note" class="form-control"></textarea>
<br />
<div align="center">
<button type="submit" class="btn btn-primary">Add Note</button>
</div>
</form>
<br>
<br>
<br>
<br>
<!-- upload Folder-->
<div class="container">
<div class="row">
<div class="col">
<h1 align="center">Datei Upload</h1>
<hr>
<form
action="http://localhost:5000/upload"
method="POST"
enctype="multipart/form-data">
<input type="file" name="file" />
<button type="submit" class="btn btn-primary">Upload</button>
</form>
</div>
</div>
</div>
<br>
<br>
<br>
<br>
<!-- download Folder-->
<div align="center">
<image src="{{ url_for('static', filename='Bilder/postgre.jpeg')}}">
</div>
<head>
<style>
table, th, td {
border: 1px solid black;
}
</style>
</head>
<body>
<h1>Downloads</h1>
<table style="width:100%; margin:auto; table-layout: fixed;">
{% for filename, mtime, size in files -%}
<tr>
<th>Dateiname</th>
<th>Datum und Uhrzeit</th>
<th>Dateigröße</th>
</tr>
<tr>
<td><a href="{{ url_for('views.download', filename=filename) }}" download>{{ filename }}</a></td>
<td>{{ moment(mtime, local=False).format('DD.MM.YYYY HH:mm') }}</td>
<td style="text-align:right;">{{ size | byte_units }}</td>
</tr>
{% endfor -%}
</table>
<script type="text/javascript">
(() => {
const elems = document.querySelectorAll('a[href][download]');
elems.forEach(elem => {
elem.addEventListener('click', evt => {
const isDonwload = window.confirm('Möchten Sie die ausgewählte Datei herunterladen??');
if (!isDonwload) { evt.preventDefault(); }
});
});
})();
</script>
{% endblock -%}
这是login.hmtl
{% extends "base.html" %} {% block title %}Login{% endblock %} {% block content
%}
<form method="POST">
<h3 align="center">Login</h3>
<div class="form-group">
<label for="email">Email Addresse</label>
<input
type="email"
class="form-control"
id="email"
name="email"
placeholder="Email Eingabe"
/>
</div>
<div class="form-group">
<label for="password">Passwort</label>
<input
type="password"
class="form-control"
id="password"
name="password"
placeholder="Passwort Eingabe"
/>
</div>
<br />
<button type="submit" class="btn btn-primary">Login</button>
</form>
{% endblock %}
这是sign_up.hmtl
{% extends "base.html" %} {% block title %}Sign Up{% endblock %} {% block
content %}
<body>
<h3 align="center"><img src="{{ url_for('static', filename='Bilder/Logo-NRL-blau.png') }}" alt=""></h3>
</body>
<form method="POST">
<h3 align="center">Sign Up</h3>
<div class="form-group">
<label for="email">Email-Addresse</label>
<input
type="email"
class="form-control"
id="email"
name="email"
placeholder="Email Eingabe"
/>
</div>
<div class="form-group">
<label for="firstName">Vollständiger Name</label>
<input
type="text"
class="form-control"
id="firstName"
name="firstName"
placeholder="Eingabe des vollständigen Namens"
/>
</div>
<div class="form-group">
<label for="password1">Passwort</label>
<input
type="password"
class="form-control"
id="password1"
name="password1"
placeholder="Passwort Eingabe"
/>
</div>
<div class="form-group">
<label for="password2">Passwort (Wiederholung)</label>
<input
type="password"
class="form-control"
id="password2"
name="password2"
placeholder="Passwort (Bestätigung)"
/>
</div>
<br />
<button type="submit" class="btn btn-primary">Submit</button>
</form>
{% endblock %}
这是base.hmtl
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
crossorigin="anonymous"
/>
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
crossorigin="anonymous"
/>
<title>{% block title %}Home{% endblock %}</title>
{{ moment.include_moment() }}
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<button
class="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbar"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbar">
<div class="navbar-nav">
{% if user.is_authenticated %}
<a class="nav-item nav-link" id="home" href="/">Home</a>
<a class="nav-item nav-link" id="logout" href="/logout">Logout</a>
{% else %}
<a class="nav-item nav-link" id="login" href="/login">Login</a>
<a class="nav-item nav-link" id="signUp" href="/sign-up">Sign Up</a>
<a class="nav-item nav-link" id="Über Uns" href="/about">Über uns</a>
{% endif %}
</div>
</div>
</nav>
{% with messages = get_flashed_messages(with_categories=true) %} {% if
messages %} {% for category, message in messages %} {% if category ==
'error' %}
<div class="alert alert-danger alter-dismissable fade show" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert">
<span aria-hidden="true">×</span>
</button>
</div>
{% else %}
<div class="alert alert-success alter-dismissable fade show" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert">
<span aria-hidden="true">×</span>
</button>
</div>
{% endif %} {% endfor %} {% endif %} {% endwith %}
<div class="container">{% block content %} {% endblock %}</div>
<script
src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"
></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"
></script>
<script
type="text/javascript"
src="{{ url_for('static', filename='index.js') }}"
></script>
</body>
</html>
玩得开心。并感谢@Detlef !!!!!!!