簡體   English   中英

如何從 Flask 模板中獲取表單數據並傳遞到 HTML 頁面

[英]How to take form data from Flask template and pass to HTML page

大家好,我是 Flask 的新手,出於某種原因,我無法完全理解這個概念。 到目前為止,我基本上擁有的是一個用戶注冊頁面。 在我的 flaskschool.py 中,我正在創建一個名為 RegistrationForm 的表單。 然后,我在我的 register.html 中為該表單創建一個模板。 在我看來 function 然后我渲染該模板並將我從表單中獲取的用戶值打印到我的 HTML 頁面。 我的目標是向用戶展示他們剛剛使用的表單以及他們剛剛在表單中為用戶名輸入的任何值的歡迎消息。 一個建議有幫助,謝謝!

襟翼.py

from flask import Flask, redirect, url_for, render_template, request, session, flash
from flask_wtf import FlaskForm
from flaskschool import DateForm, RegistrationForm
from upload import UploadForm

app = Flask(__name__)
# for decrypting session data
app.secret_key = "testb"

@app.route("/")
def home():
    return render_template("index.html")

## test site for user registration/
@app.route('/register', methods=['GET', 'POST'])
def register():
    form = RegistrationForm()
    if form.validate_on_submit(): 
        user = form.username.data
        email = form.email.data 
    return render_template('register.html', form=form, user=user)

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

燒瓶學校.py

from wtforms import Form, BooleanField, StringField, PasswordField, validators
from wtforms.fields.html5 import DateField, DateTimeField
from flask_wtf import FlaskForm
from datetime import date

## playing with custom validators
def validate_username(form, field):
    if len(field.data) > 25:
        raise validator.ValidationError("Username must be less than 25 characters")


class RegistrationForm(FlaskForm):
    username = StringField('Username', [validate_username])
    email = StringField('Email Address', [validators.Length(min=6, max=35)])
    password = PasswordField('New Password', [validators.DataRequired(),
        validators.EqualTo('confirm', message='Passwords must match')])
    confirm = PasswordField('Repeat Password')
    accept_tos = BooleanField('I accept the TOS', [validators.DataRequired()])
    enter code here

寄存器.html

{% from "_formhelpers.html" import render_field %}
<form method="POST" action="/register">
  <dl>
  </dl>
    {{ render_field(form.username) }}
    {{ render_field(form.email) }}
    {{ render_field(form.password) }}
    {{ render_field(form.confirm) }}
    {{ render_field(form.accept_tos) }}
  </dl>
  <p><input type=submit value=submit>
</div>
</form>
<br>
<h1>Welcome: {{user}}</h1>
<br> 

如果您想檢索注冊用戶的信息,您需要使用數據庫。 您將能夠查詢數據庫以檢索用戶的信息,並將其呈現在模板中。

除了需要做的一些小的修改以及可以添加的一些內容之外,您在上面還有很多事情要做。 我從一開始就開始了,所以你可以跟進:

  1. 創建一個簡單的應用程序以確保 flask 的每個部分都正常工作
  2. 配置您的應用程序以使用 web forms 和數據庫
  3. 創建一個簡單的數據庫(我將使用sqlite 。您可以根據需要使用任何其他數據庫)
  4. 創建注冊和登錄表單結構
  5. 在 HTML 模板中顯示 forms
  6. 使用視圖函數渲染這些模板

在構建應用程序時考慮使用以下結構。 在構建應用程序時遵循關注點分離原則是很方便的,因為應用程序的各個部分都聚集在模塊中。

project
   | --- flapp.py
   | --- config.py
   | --- .flaskenv
   | --- app/
          | --- __init__.py
          | --- routes.py
          | --- models.py
          | --- forms.py
          | --- templates/
                  | --- base.html
                  | --- home.html
                  | --- register.html
                  | --- login.html
          | --- static/

1. 創建一個應用程序實例並確保初始項目正在運行

  • 在你的虛擬環境中安裝flask , flask-wtf , flask-login , email-validator , python-dotev

__init__.py文件中初始化這些包:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager
from config import Config

app = Flask(__name__)
app.config.from_object(Config)

db = SQLAlchemy(app)
migrate = Migrate(app, db)
login = LoginManager(app)
login.login_view = 'login'

from app import routes, models

我添加了login.login_view = 'login'將用於保護主頁不被匿名用戶訪問。 我還從我們將在下面一節中創建的配置模塊中導入了Config class。

# flapp.py

from app import app

此文件充當 flask 應用程序的入口點。

# routes.py

from app import app

@app.route('/')
@app.route('/home')
def home:
    return 'home'

當您運行應用程序時, home()視圖 function 將返回文本“home”。

# .flaskenv

FLASK_APP=school.py
FLASK_ENV=development
FLASK_DEBUG=True

Flask 在啟動服務器之前需要這些變量。 之前安裝的 package python-dotenv用於加載它們,而不必在輸入flask run之前在終端中傳遞每個變量。

當您運行應用程序時,您應該會看到“主頁”。

2. 配置應用

安裝flask-sqlalchemyflask-migrate 它們是運行和管理數據庫所必需的。 各個變量從os.environ.get初始化。

import os
basedir = os.path.abspath(os.path.dirname(__file__))


class Config(object):
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'difficult-to-guess'
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
        'sqlite:///' + os.path.join(basedir, 'app.db')
    SQLALCHEMY_TRACK_MODIFICATIONS = False

隨意將數據庫更改為您想要的任何一個。 使用 web forms 時需要SECRET_KEY

3.創建數據庫

# models.py

from app import db, login
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin


class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), index=True, unique=True)
    email = db.Column(db.String(120), index=True, unique=True)
    password_hash = db.Column(db.String(128))

    def __repr__(self):
        return '<User {}>'.format(self.username)

    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.password_hash, password)


@login.user_loader
def load_user(id):
    return User.query.get(int(id))

要創建此數據庫,請在終端中運行以下命令:

# create a migration repository
(venv)$ flask db init 

# Create a migration script
(venv)$ flask db migrate -m 'user table'

# Apply the changes
(venv)$ flask db upgrade

這將創建一個User表,其中包含usernameemail和散列password的列。 建議不要將用戶密碼存儲在數據庫中,而是將其存儲為 hash 形式的表示形式。

4.簡單的表單結構

注冊表將如下所示:

# register.html

{% extends "base.html" %}

{% block content %}
    <h1>Register</h1>
    <form action="" method="post">
        {{ form.hidden_tag() }}
        <p>
            {{ form.username.label }}<br>
            {{ form.username(size=32) }}<br>
            {% for error in form.username.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>
            {{ form.email.label }}<br>
            {{ form.email(size=32) }}<br>
            {% for error in form.email.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>
            {{ form.password.label }}<br>
            {{ form.password(size=32) }}<br>
            {% for error in form.password.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>
            {{ form.password2.label }}<br>
            {{ form.password2(size=32) }}<br>
            {% for error in form.password2.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>{{ form.submit() }}</p>
    </form>
{% endblock %}

登錄表單將如下所示:

# login.html

{% extends "base.html" %}

{% block content %}
    <h1>Sign In</h1>
    <form action="" method="post" novalidate>
        {{ form.hidden_tag() }}
        <p>
            {{ form.username.label }}<br>
            {{ form.username(size=32) }}<br>
            {% for error in form.username.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>
            {{ form.password.label }}<br>
            {{ form.password(size=32) }}<br>
            {% for error in form.password.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>{{ form.remember_me() }} {{ form.remember_me.label }}</p>
        <p>{{ form.submit() }}</p>
    </form>
    <p>New here? <a href="{{ url_for('register') }}">Register now!</a></p>
{% endblock %}

這兩個模板都使用關鍵字extends繼承了base模板的結構。 因此,這個 base.html 文件將如下所示:

# base.html

<html>
    <head>
        {% if title %}
        <title>{{ title }} - demo</title>
        {% else %}
        <title>so demo</title>
        {% endif %}
    </head>
    <body>
        <div>
            SO Demo:
            <a href="{{ url_for('home') }}">Home</a>
            {% if current_user.is_anonymous %}
            <a href="{{ url_for('login') }}">Login</a>
            {% else %}
            <a href="{{ url_for('logout') }}">Logout</a>
            {% endif %}
        </div>
        <hr>
        {% with messages = get_flashed_messages() %}
        {% if messages %}
        <ul>
            {% for message in messages %}
            <li>{{ message }}</li>
            {% endfor %}
        </ul>
        {% endif %}
        {% endwith %}
        {% block content %}{% endblock %}
    </body>
</html>

每次用戶嘗試注冊或登錄其帳戶時,都會出現 flash 消息。 這顯示在基本模板中。

主頁將如下所示:

# home.html

{% extends "base.html" %}

{% block content %}
    <p>
        Hi {{ current_user.username }},<br><br>
        These are your details:
    </p>
    <p>
        Name: {{ current_user.username }}<br>
        Email: {{ current_user.email }}<br>
        Hashed Password: {{ current_user.password_hash }}
    </p>
{% endblock %}

我們正在顯示存儲在數據庫中的current_user的詳細信息。

處理所有這些信息的視圖函數包括home()register()login()和另外的logout() ,如下所示:

from flask import render_template, flash, redirect, url_for, request
from app import app, db
from app.forms import LoginForm, RegistrationForm
from flask_login import current_user, login_user, logout_user
from app.models import User
from flask_login import login_required
from werkzeug.urls import url_parse


@app.route('/')
@app.route('/home')
@login_required
def home():
    return render_template('home.html')


@app.route('/login', methods=['GET', 'POST'])
def login():
    if current_user.is_authenticated:
        return redirect(url_for('index'))
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user is None or not user.check_password(form.password.data):
            flash('Invalid username or password')
            return redirect(url_for('login'))
        login_user(user, remember=form.remember_me.data)
        next_page = request.args.get('next')
        if not next_page or url_parse(next_page).netloc != '':
            next_page = url_for('home')
        return redirect(next_page)
    return render_template('login.html', title='Sign In', form=form)


@app.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('home'))


@app.route('/register', methods=['GET', 'POST'])
def register():
    if current_user.is_authenticated:
        return redirect(url_for('home'))
    form = RegistrationForm()
    if form.validate_on_submit():
        user = User(username=form.username.data, email=form.email.data)
        user.set_password(form.password.data)
        db.session.add(user)
        db.session.commit()
        flash('Congratulations, you are now a registered user!')
        return redirect(url_for('login'))
    return render_template('register.html', title='Register', form=form)

你應該有這個:

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM