Sqlalchemy模型中的过程字段(使用Blask_Sqlalchemy)



我正在通过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))

相关内容

  • 没有找到相关文章

最新更新