[英]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>
如果您想檢索注冊用戶的信息,您需要使用數據庫。 您將能夠查詢數據庫以檢索用戶的信息,並將其呈現在模板中。
除了需要做的一些小的修改以及可以添加的一些內容之外,您在上面還有很多事情要做。 我從一開始就開始了,所以你可以跟進:
sqlite
。您可以根據需要使用任何其他數據庫)在構建應用程序時考慮使用以下結構。 在構建應用程序時遵循關注點分離原則是很方便的,因為應用程序的各個部分都聚集在模塊中。
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/
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
之前在終端中傳遞每個變量。
當您運行應用程序時,您應該會看到“主頁”。
安裝flask-sqlalchemy
, flask-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
。
# 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
表,其中包含username
、 email
和散列password
的列。 建議不要將用戶密碼存儲在數據庫中,而是將其存儲為 hash 形式的表示形式。
注冊表將如下所示:
# 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.