Flask-Admin Bootstrap 4 X-editable date 导致错误
Flask-Admin Bootstrap 4 X-editable date causes error
@Joes 我想我在 Flask-Admin 的 X 可编辑日期中找到了一个 error/bug,但只在 Bootstrap 4.
注意下面的代码,template_mode='bootstrap3'
工作正常,但是`template_mode='bootstrap4' 导致错误。
重现错误的代码:
import os
import datetime
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import flask_admin as admin
from flask_admin.contrib.sqla import ModelView
# Create application
app = Flask(__name__)
# Create dummy secrey key so we can use sessions
app.config['SECRET_KEY'] = '123456789'
# Create in-memory database
app.config['DATABASE_FILE'] = 'sample_db.sqlite'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + app.config['DATABASE_FILE']
app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)
# Instantiate the admin class with Bootstrap mode
# admin = admin.Admin(app, 'Example', template_mode='bootstrap3')
admin = admin.Admin(app, 'Example', template_mode='bootstrap4')
# Models
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Unicode(64))
email = db.Column(db.Unicode(64))
date_added = db.Column(db.Date)
def __unicode__(self):
return self.name
class UserAdmin(ModelView):
column_searchable_list = ('name', 'email')
column_editable_list = ('name', 'email', 'date_added')
column_display_pk = True
can_set_page_size = True
# the number of entries to display in the list view
page_size = 5
# Add Flask-Admin views
admin.add_view(UserAdmin(User, db.session))
# Flask normal views
@app.route('/')
def index():
return '<a href="/admin/">Click me to get to Admin!</a>'
def build_sample_db():
"""Populate a small db with some example entries"""
db.drop_all()
db.create_all()
first_names = [
'Harry', 'Amelia', 'Oliver', 'Jack', 'Isabella', 'Charlie','Sophie', 'Mia',
]
last_names = [
'Brown', 'Smith', 'Patel', 'Jones', 'Williams', 'Johnson', 'Taylor', 'Thomas',
]
for i in range(len(first_names)):
user = User()
user.name = first_names[i] + " " + last_names[i]
user.email = first_names[i].lower() + "@example.com"
user.date_added = datetime.date.today()
db.session.add(user)
db.session.commit()
return
# Build a sample db on the fly, if one does not exist yet.
app_dir = os.path.realpath(os.path.dirname(__file__))
database_path = os.path.join(app_dir, app.config['DATABASE_FILE'])
os.remove(database_path)
if not os.path.exists(database_path):
build_sample_db()
if __name__ == '__main__':
# Start app
app.run(debug=True, host='0.0.0.0')
错误发生前,Bootstrap 4 的 Flask-Admin 视图如下所示:
这是 JavaScript 控制台中的错误,当我单击“可编辑”日期字段时:
这是使用 template_mode='bootstrap3'
的样子(即它应该做什么):
似乎与 this issue 和需要删除的 data-template
有关。
Flask-Admin 不会删除此日期字段的 data-template
,因为它只是给了一个 data-role='x-editable'
而不是 lf x-editable-combodate
.
至少有两种方法可以解决这个问题(在 JavaScript“forms.js”或 XEditableWidget class 的 get_kwargs()
方法中)。我选择在get_kwargs()
方法中修复如下:
class XEditableWidget(object):
# ...
def get_kwargs(self, field, kwargs):
"""
Return extra kwargs based on the field type.
"""
if field.type == 'StringField':
kwargs['data-type'] = 'text'
# ...
elif field.type == 'DateField':
kwargs['data-type'] = 'combodate'
kwargs['data-format'] = 'YYYY-MM-DD'
# Remove the following so JavaScript doesn't have to do it
# kwargs['data-template'] = 'YYYY-MM-DD'
# Use the following so it adjusts the template
kwargs['data-role'] = 'x-editable-combodate'
这是页面加载时“form.js”文件中发生的情况(即在最新的 Flask-Admin“master”分支中删除了 data-template
属性):
case 'x-editable':
// No removal of the "data-template" attribute
$el.editable({
params: overrideXeditableParams,
combodate: {
// prevent minutes from showing in 5 minute increments
minuteStep: 1,
maxYear: 2030,
}
});
return true;
case 'x-editable-combodate':
// Fixes bootstrap4 issue where data-template breaks bs4 popover.
// https://github.com/flask-admin/flask-admin/issues/2022
let template = $el.data('template');
$el.removeAttr('data-template');
$el.editable({
params: overrideXeditableParams,
template: template,
combodate: {
// prevent minutes from showing in 5 minute increments
minuteStep: 1,
maxYear: 2030,
}
});
return true;
出于某种原因,生成的弹出窗口现在有点难看,但至少在功能上它可以工作!
@Joes 我想我在 Flask-Admin 的 X 可编辑日期中找到了一个 error/bug,但只在 Bootstrap 4.
注意下面的代码,template_mode='bootstrap3'
工作正常,但是`template_mode='bootstrap4' 导致错误。
重现错误的代码:
import os
import datetime
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import flask_admin as admin
from flask_admin.contrib.sqla import ModelView
# Create application
app = Flask(__name__)
# Create dummy secrey key so we can use sessions
app.config['SECRET_KEY'] = '123456789'
# Create in-memory database
app.config['DATABASE_FILE'] = 'sample_db.sqlite'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + app.config['DATABASE_FILE']
app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)
# Instantiate the admin class with Bootstrap mode
# admin = admin.Admin(app, 'Example', template_mode='bootstrap3')
admin = admin.Admin(app, 'Example', template_mode='bootstrap4')
# Models
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Unicode(64))
email = db.Column(db.Unicode(64))
date_added = db.Column(db.Date)
def __unicode__(self):
return self.name
class UserAdmin(ModelView):
column_searchable_list = ('name', 'email')
column_editable_list = ('name', 'email', 'date_added')
column_display_pk = True
can_set_page_size = True
# the number of entries to display in the list view
page_size = 5
# Add Flask-Admin views
admin.add_view(UserAdmin(User, db.session))
# Flask normal views
@app.route('/')
def index():
return '<a href="/admin/">Click me to get to Admin!</a>'
def build_sample_db():
"""Populate a small db with some example entries"""
db.drop_all()
db.create_all()
first_names = [
'Harry', 'Amelia', 'Oliver', 'Jack', 'Isabella', 'Charlie','Sophie', 'Mia',
]
last_names = [
'Brown', 'Smith', 'Patel', 'Jones', 'Williams', 'Johnson', 'Taylor', 'Thomas',
]
for i in range(len(first_names)):
user = User()
user.name = first_names[i] + " " + last_names[i]
user.email = first_names[i].lower() + "@example.com"
user.date_added = datetime.date.today()
db.session.add(user)
db.session.commit()
return
# Build a sample db on the fly, if one does not exist yet.
app_dir = os.path.realpath(os.path.dirname(__file__))
database_path = os.path.join(app_dir, app.config['DATABASE_FILE'])
os.remove(database_path)
if not os.path.exists(database_path):
build_sample_db()
if __name__ == '__main__':
# Start app
app.run(debug=True, host='0.0.0.0')
错误发生前,Bootstrap 4 的 Flask-Admin 视图如下所示:
这是 JavaScript 控制台中的错误,当我单击“可编辑”日期字段时:
这是使用 template_mode='bootstrap3'
的样子(即它应该做什么):
似乎与 this issue 和需要删除的 data-template
有关。
Flask-Admin 不会删除此日期字段的 data-template
,因为它只是给了一个 data-role='x-editable'
而不是 lf x-editable-combodate
.
至少有两种方法可以解决这个问题(在 JavaScript“forms.js”或 XEditableWidget class 的 get_kwargs()
方法中)。我选择在get_kwargs()
方法中修复如下:
class XEditableWidget(object):
# ...
def get_kwargs(self, field, kwargs):
"""
Return extra kwargs based on the field type.
"""
if field.type == 'StringField':
kwargs['data-type'] = 'text'
# ...
elif field.type == 'DateField':
kwargs['data-type'] = 'combodate'
kwargs['data-format'] = 'YYYY-MM-DD'
# Remove the following so JavaScript doesn't have to do it
# kwargs['data-template'] = 'YYYY-MM-DD'
# Use the following so it adjusts the template
kwargs['data-role'] = 'x-editable-combodate'
这是页面加载时“form.js”文件中发生的情况(即在最新的 Flask-Admin“master”分支中删除了 data-template
属性):
case 'x-editable':
// No removal of the "data-template" attribute
$el.editable({
params: overrideXeditableParams,
combodate: {
// prevent minutes from showing in 5 minute increments
minuteStep: 1,
maxYear: 2030,
}
});
return true;
case 'x-editable-combodate':
// Fixes bootstrap4 issue where data-template breaks bs4 popover.
// https://github.com/flask-admin/flask-admin/issues/2022
let template = $el.data('template');
$el.removeAttr('data-template');
$el.editable({
params: overrideXeditableParams,
template: template,
combodate: {
// prevent minutes from showing in 5 minute increments
minuteStep: 1,
maxYear: 2030,
}
});
return true;
出于某种原因,生成的弹出窗口现在有点难看,但至少在功能上它可以工作!