我的目标很简单,我创建了一个接收 ID 的路由。
@app.route('/afbase/<int:pid>', methods=["GET", "PATCH", "DELETE"])
# We defined the page that will retrieve some info
def show(pid):
new_person = People.query.filter_by(pid=pid).first()
我不希望这个 ID 显示给最终用户。如何散列路由或部分散列路由?
这个路由会接收到一个名为PID的变量,你可以看到,这个PID变量可以看作是一个ID。不区分大小写,但不能在浏览器 URL 上显示。
我尝试使用 hashlib 但没有成功。
您可以使用
hashids
库对整数 ID 进行编码和解码。首先,pip install hashids
。然后,创建一些实用函数。
# utils.py
from flask import current_app
from hashids import Hashids
def create_hashid(id):
hashids = Hashids(min_length=5, salt=current_app.config['SECRET_KEY'])
hashid = hashids.encode(id)
return hashid
def decode_hashid(hashid):
hashids = Hashids(min_length=5, salt=current_app.config['SECRET_KEY'])
id = hashids.decode(hashid)
return id
接下来,创建一个全局环境变量,这样您就可以从您的 jinja2 模板中调用 create_hashid 函数:
# app.py
from utils import create_hashid
app.jinja_env.globals.update(create_hashid=create_hashid)
以下是如何从模板中的链接调用该函数:
# index.html
<a href="{{ url_for('invoice.view_invoice', hashid=create_hashid(invoice.id) ) }}">View Invoice</a>
最后,你的视图函数:
# views.py
@blueprint.route('/dashboard/invoice/<hashid>')
@login_required
def view_invoice(hashid):
invoice_id = decode_hashid(hashid)
invoice = Invoice.query.filter_by(
user_id=current_user.id,
id=invoice_id
).first_or_404()
return render_template(
'dashboard/invoice/view_invoice.html',
invoice=invoice
)
我知道 OP 已经有了答案。然而,我发现了一个很棒的 Flask 扩展,叫做 Flask-Hashids,它基本上基于 Bob 的答案中使用的 hashids,但更优雅。
可重现的代码
from flask import Flask, url_for
from flask_hashids import HashidMixin, Hashids
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SECRET_KEY'] = 'super-secret-key'
app.config['HASHIDS_SALT'] = 'must-be-different-from-SECRET_KEY'
app.config['HASHIDS_MIN_LENGTH'] = 16
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db_dev.sqlite3'
db = SQLAlchemy(app)
hashids = Hashids(app)
class User(HashidMixin, db.Model): # Add the hashid mixin class
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), nullable=False)
@property
def url(self):
# The HashidConverter encodes the given id to a hashid in the URL
return url_for('user', user_id=self.id)
def to_json(self):
return {"id": self.hashid, "name": self.name}
@app.before_first_request
def create_user_table():
db.create_all()
# Add some dummy data
db.session.add_all([User(name='John Doe'), User(name='Jane Doe')])
db.session.commit()
@app.route('/user')
def users():
users = User.query.all() # get all users
return [user.to_json() for user in users], 200
输出
[
{
"id": "RxvDmWYG8neBo098", # Hashed ID
"name": "John Doe"
},
{
"id": "yaAxNdnWbYgk4oeZ", # Hashed ID
"name": "Jane Doe"
}
]