我正在通过blask_sqlalchemy使用sqlalchemy。模型从HTML表单接收输入。我希望将此输入剥离任何标签。我认为在分配前的代码中没有多次在代码中进行此操作,而是以某种方式在模型对象中实现此功能。
。我能想到的可能性是:
- 衍生自己的列类型
- 围绕列类型包裹代理类
- 定义一种进行上述装饰师
- 将模型对象修改为拦截作业
前三个解决方案似乎更优雅,但我不明白我需要如何实施这些解决方案。主要原因是我不了解如何确切地从列变量中提取表结构和列类型,以及如何处理这些分配,特别是当通过blask_sqlalchemy类访问时。
。我在上面列表中使用了最后一个选项,并提出了这个(部分(解决方案:
import bleach
class Example(db.Model):
__tablename__ = 'examples'
id = db.Column(db.Integer, primary_key=True)
field1 = db.Column(db.Text)
field2 = db.Column(db.String(64))
_bleach_columns = ('field1', 'field2')
def __init__(self, **kwargs):
if kwargs is not None:
for key in Example._bleach_columns:
kwargs[key] = bleach.clean(kwargs[key], tags=[], strip=True)
super(Example, self).__init__(**kwargs)
使用Example(field1='foo', field2='bar')
创建对象时,这起作用。但是,我不确定如何处理各个字段的分配。我当时想着这些行,但不确定标记为分配的零件:
def __setattr__(self, attr, obj):
if(attr in Example._bleach_columns):
ASSIGN(..... , bleach.clean(obj, tags=[], strip=True))
else:
ASSIGN(..... , obj)
更一般而言,我的印象是,这不是处理标签过滤的最佳方法。因此,我感谢您如何最好地实施这种行为的任何暗示,理想情况下是通过新列类型的装饰器。
看起来可以使用应用process_bind_param
中的漂白剂的TypeDecorator(链接(来完成。但是,我无法弄清楚如何将此装饰器应用于db.model衍生的类别的基于blask_sqlalchemy的列定义。
我终于设法解决了这个问题...像往常一样,一旦人们了解一切。
第一件事是了解db.Column
与SQLalchemy的column
相同。因此,我可以使用相同的语法。为了实现可变长度字符串,我使用了一家工厂来返回装饰器。如果还有另一个解决方案可以实施长度,我将有兴趣听到有关该长度的消息。无论如何,这是代码:
def bleachedStringFactory(len):
class customBleachedString(types.TypeDecorator):
impl = types.String(len)
def process_bind_param(self, value, dialect):
return bleach.clean(value, tags=[], strip=True)
def process_result_value(self, value, dialect):
return value
return customBleachedString
class Example(db.Model):
__tablename__ = 'examples'
id = db.Column(db.Integer, primary_key=True)
field1 = db.Column(bleachedStringFactory(64), unique=True)
field2 = db.Column(bleachedStringFactory(128))