此问题困扰了我很长一段时间,我搜索了几天但仍然无法解决问题,包括this,this和this。
下面的代码返回一个查询对象,它在选择字段中正确显示。 但是在提交到数据库时,发生了错误。
# Query the user with Role.id == 4 as reviewer
def reviewer_choices():
return User.query.join(User.roles).filter(Role.id == 4)
# Build a select field
class ProjectView(sqla.ModelView):
form_extra_fields = {
'reviewer': sqla.fields.QuerySelectField(
query_factory=reviewer_choices,
)}
我尝试定义__repr__
和__str__
以便将其转换为字符串但是徒劳无功,还有其他方法可以将查询对象转换为字符串吗?提前谢谢。
1。 __repr __ : 错误返回:
sqlalchemy.exc.InterfaceError InterfaceError:
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(255))
# ...
# ...
def __repr__(self):
return self.first_name
2。 __str __ : 错误返回:
sqlalchemy.exc.InterfaceError InterfaceError :(由于提出的结果) 查询调用autoflush;考虑使用session.no_autoflush块 如果这个刷新过早发生)(sqlite3.InterfaceError)错误 绑定参数8 - 可能不受支持的类型。 [SQL:你' INSERT INTO 项目
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(255))
# ...
# ...
def __str__(self):
return self.first_name
我目前使用:
在Project类
中class Project(db.Model):
# ...
reviewer = db.Column(db.Unicode(128))
# ...
在项目表
中CREATE TABLE `project` (
# ...
`reviewer1` TEXT,
# ...
答案 0 :(得分:1)
假设在项目模型中将reviewer
作为字符串字段是有意的(而不是关系)。
QuerySelectField
数据属性存储ORM实例,在您的情况下是User
模型的实例,而您的reviewer
字段是字符串,因此出现错误消息。
您可以创建一个继承的QuerySelectField
类并覆盖其populate_obj
方法,将选定的User实例转换为您选择的字符串,例如。
class ProjectQuerySelectField(QuerySelectField):
def populate_obj(self, obj, name):
# obj is the current model being edited/created
# name is the field name - 'reviewer' in this instance
# self.data is the user instance selected in the form
setattr(obj, name, str(self.data))
请注意使用str
函数来获取所选用户实例的字符串表示形式。
请参阅下面的自包含示例应用。导航到http://127.0.0.1:5000/admin/project/以查看所选用户如何转换为字符串。
from flask import Flask
from flask_admin.contrib.sqla import ModelView
from flask_admin.contrib.sqla.fields import QuerySelectField
from flask_security import Security, SQLAlchemyUserDatastore, RoleMixin, UserMixin
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admin
# Create application
app = Flask(__name__)
# Create dummy secrey key so we can use sessions
app.config['SECRET_KEY'] = '123456790'
# 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)
# Flask views
@app.route('/')
def index():
return '<a href="/admin/">Click me to get to Admin!</a>'
# Define models
roles_users = db.Table('roles_users',
db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))
class Role(db.Model, RoleMixin):
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(255), unique=True)
description = db.Column(db.String(255))
def __str__(self):
return unicode(self).encode('utf-8')
def __unicode__(self):
return self.name
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(255))
last_name = db.Column(db.String(255))
email = db.Column(db.String(254), unique=True)
roles = db.relationship('Role', secondary=roles_users, backref=db.backref('users', lazy='dynamic'))
def __str__(self):
return unicode(self).encode('utf-8')
def __unicode__(self):
return ', '.join(filter(None, [self.first_name, self.last_name, self.email]))
class Project(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255))
reviewer = db.Column(db.Unicode(128))
def __str__(self):
return unicode(self).encode('utf-8')
def __unicode__(self):
return self.name
# Setup Flask-Security
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)
class UserView(ModelView):
column_list = ['first_name', 'last_name', 'email', 'roles']
form_columns = ['first_name', 'last_name', 'email', 'roles']
class RoleView(ModelView):
form_columns = ['name', 'description']
def reviewer_choices():
# return User.query.join(User.roles).filter(Role.id == 4)
return User.query.join(User.roles).filter(Role.name == u'Reviewer')
class ProjectQuerySelectField(QuerySelectField):
def populate_obj(self, obj, name):
setattr(obj, name, str(self.data))
class ProjectView(ModelView):
form_extra_fields = {
'reviewer': ProjectQuerySelectField(
query_factory=reviewer_choices,
)}
admin = Admin(app, template_mode="bootstrap3")
admin.add_view(UserView(User, db.session))
admin.add_view(RoleView(Role, db.session))
admin.add_view(ProjectView(Project, db.session))
def build_sample_db():
db.drop_all()
db.create_all()
# Reviewer will have id : 4 and will have index 3 in _roles list
_roles = []
for _name in ['Admin', 'Editor', 'Reader', 'Reviewer']:
_role = Role(name=_name)
_roles.append(_role)
db.session.add_all(_roles)
# get the "Reviewer" Role
_reviewer_role = _roles[3]
# Give Paul and Serge "Reviewer" role
_user_1 = User(first_name="Paul", last_name="Cunningham", email="paul@example.com", roles=[_reviewer_role])
_user_2 = User(first_name="Luke", last_name="Brown", email="luke@example.com")
_user_3 = User(first_name="Serge", last_name="Koval", email="serge@example.com", roles=[_reviewer_role])
db.session.add_all([_user_1, _user_2, _user_3])
db.session.commit()
if __name__ == '__main__':
build_sample_db()
app.run(port=5000, debug=True)