如何使用flask(使用引导程序)和python列出目录中的文件?

发布于 2025-01-10 16:07:44 字数 2045 浏览 0 评论 0原文

这是我在这个论坛上提出的第一个问题。我非常渴望找到解决方案...希望我能向你们学习。 我有一个解决方案,但是在浏览器窗口中发布整个目录树并知道文件名,这不是我想要的。

现在我找到了这样的代码片段并对其进行了一些修改。它的生成器表达式,我认为 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 时,我无法列出文件并且打印功能为空。三天以来,我一直坐在它上面,甚至没有错误消息,这对我有帮助。

这是我对 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 模板的原始截取(它是 %extended%),循环遍历返回的文件(我希望.. .):

<!-- 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>

现在的问题是:我必须在两个文件中更改什么才能在本地网页上看到这 3 个文件 (http://127.0.0.1:5000/)?我想列出它们并使它们可单击,因此在单击时,可以将文件作为附件下载。第二件事是列出它们的上传时间。第三件事是,下载过程中会弹出一个窗口,询问我“您想下载(文件名)吗?为了形象化我的问题,我上传了一张图像并画了红色框。感谢您提供的每一个帮助.

图片链接:(https://i.sstatic.net/pFKrP.jpg

)已经找到这篇文章,在我的脚本中说树未定义(用flask列出目录中的文件< /a>),所以我放弃了。

This is my first Question I make on this forum. I am so desperate to find a solution... Hope I can learn from you guys.
I had a solution, but with posting the whole directorytree in the browserwindow and knowing the filename, which is not like I want it.

Now I found such code snippet and changed it a little bit. Its generator expression, which is I think not supported with 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)

The output gives me 3 files inside the path:
1.jpeg
postgre.jpeg
winrar-x64-610d.exe

I am trying to make a list and pass it to JINJA2. I have created already a template, but somehow, when I run flask, I cant list the files and the print function is empty. Since 3 days I am sitting on it and there is not even an error message, which could help me.

This is my original outtake of auth.py (imports of libraries are fine, not listed here):

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://i.sstatic.net/pFKrP.jpg)

I have found this article, which says in my script that tree is undefined (List files in directories with flask), so I gave it up.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我的鱼塘能养鲲 2025-01-17 16:07:44

你确实可以在 jinja2 中使用生成器。
我写的例子应该可以满足你的需求。
它将目录中的文件显示为列表。每个条目都有其大小和上传时间。 uploads 文件夹位于 实例文件夹 中,以分隔来自应用程序的文件。
我使用 flask-moment 显示正确的时间。它使用 moment.js 并显示客户端各自时区的时间戳。
我使用自定义 Jinja2 过滤器 来显示文件大小.
如果单击文件进行下载,则会打开一个对话框,要求确认。这是使用 JavaScript 完成的。
享受实现目标的乐趣。

Flask (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!')
(网站/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)
(网站/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 -%}

You can indeed use a generator inside jinja2.
The example I wrote should meet your needs.
It displays the files within the directory as a list. Each entry is assigned its size and the time of upload. The uploads folder is inside the instance folder to separate the files from the application.
I use flask-moment to show the correct times. This uses moment.js and displays the timestamp in the respective time zone of the client.
I use a custom Jinja2 filter to display the file size.
If a file is clicked to download, a dialog opens that requests confirmation. This is done using JavaScript.
Have fun achieving your goals.

Flask (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>

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 -%}
萝莉病 2025-01-17 16:07:44

在 @ 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!!!!!!!

With the help of @ Detlef a local webserver was created, which allows you to log in, sign up and leave notes. Then there were an upload and a download option set up.

I begin with the tree structure.

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
|    

Starting with the main.py:

from website import create_app # website folder

app = create_app()

if __name__ == '__main__':
    app.run(debug=True)

This is the 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)

This is the 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
    )

This is the 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!')

This is the 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')

THis is the home.html template:

{% 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 -%}

This is the 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 %}

This is the 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 %}

This is the 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>

Have fun with it. AND THANKS to @ Detlef !!!!!!!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文