繁体   English   中英

SQLAlchemy 模型中的处理字段(使用flask_sqlalchemy)

[英]Process fields in SQLAlchemy model (using flask_sqlalchemy)

我正在通过flask_sqlalchemy 使用SQLAlchemy。 模型接收来自 HTML 表单的输入。 我希望这个输入被剥离任何标签。 与其在赋值之前在代码中多次执行此操作,我认为最好在模型对象中以某种方式实现它。

我能想到的可能性是:

  • 派生自己的列类型
  • 围绕列类型包装一个代理类
  • 定义一种执行上述操作的装饰器
  • 修改模型对象拦截赋值

前三个解决方案看起来更优雅,但我不明白我需要如何实现这些。 主要原因是我不明白 SQLAlchemy 如何从列变量中提取表结构和列类型,以及如何处理对这些的分配,特别是在通过 flask_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')创建对象时有效。 但是,我不确定如何处理各个字段的分配。 我正在考虑这些方面的事情,但不确定标记为 ASSIGN 的部分:

    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 ( link ) 来完成。 但是,我无法弄清楚如何将此装饰器应用于上述 db.Model 派生类中基于 flask_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))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM