Python 编辑主键具有枚举的记录时发生Flask admin错误
使用postgres并尝试编辑包含枚举的主键的记录将出现错误 这是因为ID包含枚举的类名,即Python 编辑主键具有枚举的记录时发生Flask admin错误,python,postgresql,flask-sqlalchemy,flask-admin,Python,Postgresql,Flask Sqlalchemy,Flask Admin,使用postgres并尝试编辑包含枚举的主键的记录将出现错误 这是因为ID包含枚举的类名,即MyEnum..ONE,而它应该仅为ONE: test.py 从枚举导入枚举 从烧瓶进口烧瓶 从flask_admin导入admin 从flask_admin.contrib.sqla导入模型视图 从flask_sqlalchemy导入sqlalchemy 从sqlalchemy导入PrimaryKeyConstraint app=烧瓶(名称) app.config['SQLALCHEMY\u DATA
MyEnum..ONE
,而它应该仅为ONE
:
test.py
从枚举导入枚举
从烧瓶进口烧瓶
从flask_admin导入admin
从flask_admin.contrib.sqla导入模型视图
从flask_sqlalchemy导入sqlalchemy
从sqlalchemy导入PrimaryKeyConstraint
app=烧瓶(名称)
app.config['SQLALCHEMY\u DATABASE\u URI']='postgresql://'
app.config['SQLALCHEMY_ECHO']=True
db=SQLAlchemy(应用程序)
MyEnum类(枚举):
一=1
类MyModel(db.Model):
id=db.Column(db.Integer)
enum=db.Column(db.enum(MyEnum))
__表参数=(
PrimaryKeyConstraint('id','enum',name='pk_mymodel'),
)
类MyAdminView(模型视图):
列\显示\主键=真
admin=admin(应用程序)
admin.add_视图(MyAdminView(MyModel,db.session))
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
#启动应用程序
db.drop_all()
db.create_all()
添加(MyModel(id=1,enum=MyEnum.ONE))
db.session.commit()
app.run(debug=True)
使用python test.py运行,然后转到并单击编辑记录:
这是因为flask\u admin
如何在URL中为给定实例构建主键值
在玩了一段时间调试器并深入研究之后,我发现这是因为MyModel
实例上enum
属性的字符串表示实际上等于'MyEnum.ONE'
str(my_model_instance.enum)==“MyEnum.ONE”
str
最终被which调用which被which调用which被which调用which被which调用结果在管理模板的url中使用
在下一个版本中,在他们可能修复此问题之前,您可以覆盖MyEnum的\uuu str\uuu
方法,以便返回其名称,然后返回str(my\u model\u instance.enum)==“ONE”
class MyEnum(Enum):
ONE = 1
def __str__(self):
return self.name
现在编辑的url是:
正如所料。这是因为flask\u admin
如何在URL中为给定实例构建主键值
在玩了一段时间调试器并深入研究之后,我发现这是因为MyModel
实例上enum
属性的字符串表示实际上等于'MyEnum.ONE'
str(my_model_instance.enum)==“MyEnum.ONE”
str
最终被which调用which被which调用which被which调用which被which调用结果在管理模板的url中使用
在下一个版本中,在他们可能修复此问题之前,您可以覆盖MyEnum的\uuu str\uuu
方法,以便返回其名称,然后返回str(my\u model\u instance.enum)==“ONE”
class MyEnum(Enum):
ONE = 1
def __str__(self):
return self.name
现在编辑的url是:
正如预期的那样。如果您不想覆盖MyEnum的\u str\u
方法,您可以覆盖MyAdminView的get\u pk\u value
方法,以便为flask admin构建正确的主键值
from enum import Enum
from flask import Flask
from flask_admin import Admin,tools
from flask_admin.contrib.sqla import ModelView
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import PrimaryKeyConstraint
class MyAdminView(ModelView):
column_display_pk = True
form_columns = ('id', 'enum')
def get_pk_value(self, model):
if isinstance(self._primary_key, tuple):
pk_values = []
for attr in self._primary_key:
value = getattr(model, attr)
if type(value) is MyEnum:
pk_values.append(value.name)
else:
pk_values.append(value)
return tools.iterencode(pk_values)
else:
return tools.escape(getattr(model, self._primary_key))
现在编辑的url是:
/admin/mymodel/edit/?id=1%2CONE&url=%2Fadmin%2Fmymodel%2F
正如预期的那样。如果您不想覆盖MyEnum的\u str\u
方法,您可以覆盖MyAdminView的get\u pk\u value
方法,以便为flask admin构建正确的主键值
from enum import Enum
from flask import Flask
from flask_admin import Admin,tools
from flask_admin.contrib.sqla import ModelView
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import PrimaryKeyConstraint
class MyAdminView(ModelView):
column_display_pk = True
form_columns = ('id', 'enum')
def get_pk_value(self, model):
if isinstance(self._primary_key, tuple):
pk_values = []
for attr in self._primary_key:
value = getattr(model, attr)
if type(value) is MyEnum:
pk_values.append(value.name)
else:
pk_values.append(value)
return tools.iterencode(pk_values)
else:
return tools.escape(getattr(model, self._primary_key))
现在编辑的url是:
/admin/mymodel/edit/?id=1%2CONE&url=%2Fadmin%2Fmymodel%2F
正如所料。感谢您对此进行调查。这是我使用的解决方法,但我希望有一种替代方法来覆盖\uuuu str\uuuu
。感谢您对此进行研究。这是我使用的解决方法,但我希望有一种替代方法来覆盖\uu str\uu
。