這是我在這個論壇上提出的第一個問題。我非常渴望找到解決方案......希望我能向你們學習。我有一個解決方案,但是在瀏覽器視窗中發布整個目錄樹并知道檔案名,這不是我想要的。
現在我找到了這樣的代碼片段并對其進行了一些更改。它的生成器運算式,我認為 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。我已經創建了一個模板,但是不知何故,當我運行燒瓶時,我無法列出檔案并且列印功能為空。由于 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))
This is my original outtake of home.html template (which was %extended%), looping through the returned files ( I wish to...):
<!-- 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>
The question is now: What do I have to change in my both files that I can see the 3 files on my local webpage (http://127.0.0.1:5000/)? I would like to list them and make them clickable, so while clicking, the file can be downloaded as attachment. Second thing is, to list them with upload time. THird thing is, that the download process, let a window popping up, which asks me "DO you wish to download (filename). To visualize my problem, I uploaded an image and drew red boxes. Thanks in regard for every help out there.
Image link: (https://imgur.com/a/z4l8zH2)
我找到了這篇文章,它在我的腳本中說樹是未定義的(使用 flask 列出目錄中的檔案),所以我放棄了它。
uj5u.com熱心網友回復:
您確實可以在 jinja2 中使用生成器。
我寫的例子應該能滿足你的需要。
它將目錄中的檔案顯示為串列。每個條目都分配有其大小和上傳時間。uploads 檔案夾位于實體檔案夾內,用于將檔案與應用程式分開。
我使用燒瓶時刻來顯示正確的時間。這使用moment.js并在客戶端的相應時區顯示時間戳。
我使用自定義 Jinja2過濾器來顯示檔案大小。
如果單擊檔案進行下載,則會打開一個要求確認的對話框。這是使用 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 (模板/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>
I've added my code to your project. It should work now.
You should work on structuring your project so that you can find your way around the code more easily. I cannot relieve you of this task in this context.
(website/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 -%}
uj5u.com熱心網友回復:
我的實體檔案夾(C:\Users\add706\Documents\NRL_webseite\instance),里面是我的上傳檔案夾(C:\Users\add706\Documents\NRL_webseite\instance\uploads)。
我的檔案夾結構:
(C:\Users\add706\Documents\NRL_webseite)這是我的 main.py:
from website import create_app # website folder
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
(C:\Users\add706\Documents\NRL_webseite\website)這是我的 auth.py:
import os
import json
from flask import Flask
from flask import Blueprint, render_template, request, flash, redirect, url_for, send_from_directory, abort, jsonify
from .models import User
from werkzeug.security import generate_password_hash, check_password_hash
from werkzeug.utils import secure_filename
from . import db
from flask_login import login_user, login_required, logout_user, current_user
from flask_moment import Moment
from datetime import datetime
auth = Blueprint('auth', __name__)
# About
@auth.route('/about')
def about():
return render_template("about.html", user=None)
@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)
# Creating the upload folder
upload_folder = "instance/uploads/"
@auth.route('/upload', methods = ['GET', 'POST'])
def uploadfile():
if request.method == 'POST': # check if the method is post
f = request.files['file'] # get the file from the files object
f.save(os.path.join(upload_folder ,secure_filename(f.filename))) # this will secure the file
return 'file uploaded successfully' # Display this message after uploading
# Creating the download
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)
)
@auth.route('/')
def index():
files = get_files(app.config['UPLOAD_FOLDER'])
return render_template('home.html', **locals())
@auth.route('/download/<path:filename>')
def download(filename):
return send_from_directory(
app.config['UPLOAD_FOLDER'],
filename,
as_attachment=True
)
我的 home.html 看起來像這樣(C:\Users\add706\Documents\NRL_webseite\website\templates)我粘貼你的 index.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>
<body>
<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>
</body>
</div>
</div>
</div>
<br>
<br>
<br>
<br>
<!-- download Folder-->
<div align="center">
<image src="{{ url_for('static', filename='uploads/postgre.jpeg')}}">
</div>
<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>
{% endblock %}
我的 base.html 看起來像這樣(C:\Users\add706\Documents\NRL_webseite\website\templates):
<!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>
</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>
這是我的views.py (C:\Users\add706\Documents\NRL_webseite\website),我在這一行收到一條錯誤訊息-> return render_template("home.html", user=current_user):
from flask import Blueprint, render_template, request, flash, jsonify
from flask_login import login_required, current_user
from .models import Note
from . import db
import json
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')
return render_template("home.html", user=current_user)
@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({})
這是我的 models.py(C:\Users\add706\Documents\NRL_webseite\website):
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')
這是我運行所有腳本的錯誤訊息:
C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask_sqlalchemy\__init__.py:872: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True or False to suppress this warning.
warnings.warn(FSADeprecationWarning(
* Running on http://127.0.0.1:5000/ (Press CTRL C to quit)
[2022-03-04 11:26:23,116] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask\app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask\app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask\app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask_login\utils.py", line 272, in decorated_view
return func(*args, **kwargs)
File "C:\Users\add706\Documents\NRL_webseite\website\views.py", line 25, in home
return render_template("home.html", user=current_user)
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask\templating.py", line 138, in render_template
ctx.app.jinja_env.get_or_select_template(template_name_or_list),
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\jinja2\environment.py", line 930, in get_or_select_template
return self.get_template(template_name_or_list, parent, globals)
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\jinja2\environment.py", line 883, in get_template
return self._load_template(name, self.make_globals(globals))
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\jinja2\environment.py", line 857, in _load_template
template = self.loader.load(self, name, globals)
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\jinja2\loaders.py", line 127, in load
code = environment.compile(source, name, filename)
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\jinja2\environment.py", line 638, in compile
self.handle_exception(source=source_hint)
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\jinja2\environment.py", line 832, in handle_exception
reraise(*rewrite_traceback_stack(source=source))
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\jinja2\_compat.py", line 28, in reraise
raise value.with_traceback(tb)
File "C:\Users\add706\Documents\NRL_webseite\website\templates\home.html", line 69, in template
<td style="text-align:right;">{{ size | byte_units }}</td>
jinja2.exceptions.TemplateAssertionError: no filter named 'byte_units'
127.0.0.1 - - [04/Mar/2022 11:26:23] "GET / HTTP/1.1" 500 -
uj5u.com熱心網友回復:
我的(我們的)新的 auth.py
import os
import json
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__)
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)
@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
)
我(我們的)新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 -%}
ERRORMESSAGE:和往常一樣
(NRL_databank) C:\Users\add706\Documents\NRL_webseite>flask run
* Serving Flask app "main"
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask_sqlalchemy\__init__.py:872: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True or False to suppress this warning.
warnings.warn(FSADeprecationWarning(
* Running on http://127.0.0.1:5000/ (Press CTRL C to quit)
[2022-03-04 16:00:05,007] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask\app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask\app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask\app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask_login\utils.py", line 272, in decorated_view
return func(*args, **kwargs)
File "C:\Users\add706\Documents\NRL_webseite\website\views.py", line 45, in home
return render_template('home.html', **locals())
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\flask\templating.py", line 138, in render_template
ctx.app.jinja_env.get_or_select_template(template_name_or_list),
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\jinja2\environment.py", line 930, in get_or_select_template
return self.get_template(template_name_or_list, parent, globals)
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\jinja2\environment.py", line 883, in get_template
return self._load_template(name, self.make_globals(globals))
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\jinja2\environment.py", line 857, in _load_template
template = self.loader.load(self, name, globals)
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\jinja2\loaders.py", line 127, in load
code = environment.compile(source, name, filename)
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\jinja2\environment.py", line 638, in compile
self.handle_exception(source=source_hint)
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\jinja2\environment.py", line 832, in handle_exception
reraise(*rewrite_traceback_stack(source=source))
File "C:\Users\add706\Anaconda3\envs\NRL_databank\lib\site-packages\jinja2\_compat.py", line 28, in reraise
raise value.with_traceback(tb)
File "C:\Users\add706\Documents\NRL_webseite\website\templates\home.html", line 63, in template
<td style="text-align:right;">{{ size | byte_units }}</td>
jinja2.exceptions.TemplateAssertionError: no filter named 'byte_units'
127.0.0.1 - - [04/Mar/2022 16:00:05] "GET / HTTP/1.1" 500 -
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/437668.html
