django ORM - 防止直接设置模型字段

时间:2016-09-12 14:01:32

标签: python django

我有一个Django类

class Chat(models.Model):
    primary_node = models.ForeignKey('nodes.Node', blank=True, null=True, related_name='chats_at_this_pri_node', on_delete=models.SET_NULL)
    secondary_node = models.ForeignKey('nodes.Node', blank=True, null=True, related_name='chats_at_this_sec_node', on_delete=models.SET_NULL)

我想禁止直接分配字段,例如

chat.primary_node = some_node

而是创建一个方法chat.assign_node(primary, secondary),通过Django Chat.update()模型方法更新节点。

原因是我想记录对这些节点的所有更改(计算更改并使用新计数更新其他模型字段),但不要求我和其他开发人员忘记我们不能直接分配字段,因为这不会t触发自定义assign_node逻辑。

我怎么做?

2 个答案:

答案 0 :(得分:1)

您可以尝试使用__setattr__阻止分配到这些字段,但我建议您不要这样做有两个原因:

  1. 这可能会引入各种意想不到的副作用
  2. 您正在运行时执行检查,以防止在编写代码时引入某些内容。这就像在每个请求上运行(微小)单元测试一样。
  3. 我只需将字段重命名为_primary_node_secondary_node,以表明这些字段是私有字段,而不是直接使用。

    此外,您可以为您的版本控制系统编写一个钩子,以检查这些字段的分配。这可能是_primary_node =的简单grep,也可能是像flake8这样的linter的插件。

答案 1 :(得分:0)

这只是禁用'primary_node'的设置

class Chat(models.Model)
    def __setattr__(self, attrname, val):
        if attrname == 'primary_node': #sets only the attribute if it's not primary_node
            print('[!] You cannot assign primary_node like that! Use assign_node() method please.')
        else:
            super(Chat, self).__setattr__(attrname, val)