如何防止在python中插入与模型不同的记录。

2024-09-27 21:35:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据模型,它有一些基本属性和数组类型属性,如下所示:

class WordCollection:
    """First model"""
    def __init__(self, **properties):
        self.name = ""
        self.status = CommonStatus.active
        self.expire_time = time.time() + 1000 * 60 * 24  # after 1 day
        self.created_date = time.time()
        self.words = []
        self.__dict__.update(properties)

这是一种恶作剧。例如,当我用一个不属于类的属性构造类时,它很容易被黑客攻击

collection = WordCollection(**{..., "hack_property":"large text or irrelative data"})

因此,我使用了类初始化方法:

class WordCollection:
        """Second model"""
        def __init__(self, **properties):
            self.name = properties["name"] if "name" in properties else ""
            self.status = properties["active"] if "active" in properties else CommonStatus.active
            self.expire_time = properties["expire_time"] if "expire_time" in properties else time.time() + 1000 * 60 * 24  # after 1 day
            self.created_date = properties["created_date"] if "created_date" in properties else time.time()
            self.words = properties["words"] if "words" in properties else []

但上述代码并不能完全解决问题:

collection = WordCollection(**{..., "name":{"hack_property":"large text or irrelative data"}})

这是最后重建的代码:

    class WordCollection:
        """Third Model"""
        def __init__(self, **properties):
            self.name = properties["name"] if "name" in properties and isinstance(properties["name"], str) else ""
            self.status = properties["active"] if "active" in properties \
                                                  and isinstance(properties["status"], int) else CommonStatus.active
            ....

上述修订解决了我的问题,但它带来了条件复杂性,我相信这将是比上述更好的解决方案


Tags: nameinselfdateif属性timestatus
1条回答
网友
1楼 · 发布于 2024-09-27 21:35:07

更标准的配方:

valid_properties =  {'prop1', 'prop2', 'prop3'}
class WordCollection(object):
    def __init__(self, name="", status=None; **properties):
        # This one is explicit, with a default that is specified in the call signature
        # Defaults in the call signature are resolved when the class is imported
        self.name = name
        # This one is more dynamic - CommonStatus.active could change
        # after the user imports the class, so we don't want it fixed.
        # Instead, use a sentinel.
        # I usually use None. If None is a valid value, best bet
        # is to do something like this:
        # sentinel = object()
        # then use that instead of None.
        self.status = CommonStatus.active if status is None else status
        # This one we just assign - 
        self.words = []
        # You don't _have_ to include a **kwargs if you don't want to.
        # If you don't want _any_ surprise properties, just leave
        # **properties out of the __init__, and only ones you explicit
        # declare will be allowed.
        # Explicit is better - they show up in tab completion/help
        # But if you want to filter out input to a set of valid props...
        filtered_props = {k:v for k,v in properties.items() if k in valid_properties}
        self.__dict__.update(filtered_props)

相关问题 更多 >

    热门问题