【问题标题】:Make a Django model read-only?将 Django 模型设为只读?
【发布时间】:2011-05-19 01:20:58
【问题描述】:

罐头上写着什么。有没有办法让 Django 模型只读?

我的意思是一个 Django 模型,其中一旦创建了记录,就无法对其进行编辑。

这对于记录交易历史的模型很有用。

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    如果您不希望修改记录的尝试静默失败:

    def save(self, *args, **kwargs):
        if self.pk:
            (raise an exception)
        super(YourModel, self).save(*args, **kwargs)
    
    
    def delete(self, *args, **kwargs):
        (raise an exception)
    

    【讨论】:

      【解决方案2】:

      除了其他解决方案:如果您的主要目标是避免管理员的写入权限,您可以修改使用的管理员类,以便没有人拥有添加/更改权限:

      class HistoryAdmin(admin.ModelAdmin):
      
          def has_add_permission(self, request):
              return False
      
          def has_change_permission(self, request, obj=None):
              return False
      
          def has_delete_permission(self, request, obj=None):
              return False
      

      【讨论】:

      • 只读意味着人们仍然可以阅读它们。如果您删除更改权限,则不再是这种情况了。
      【解决方案3】:

      如果你愿意,你可以覆盖 save 方法而不是调用 super。这将是一种相当简单的方法。

      # blatantly ripped the save from another answer, since I forgot to save original model
      def save(self, *args, **kwargs):
          if self.id is None:
              super(ModelName, self).save(*args, **kwargs)
      
      def delete(self, *args, **kwargs):
          return
      

      如果尝试进行删除或更新而不是简单地返回,您可能还应该引发异常。您想向用户表明正在发生的事情 - 行为无效。

      【讨论】:

      • 我如何首先创建该模型的实例?
      • 是的,我忘了检查 id 是否是更新或保存。我已经更新了答案。
      • +1 建议在更新/删除时抛出异常以通知用户。
      【解决方案4】:

      您可以覆盖模型的保存方法并检查它是否是现有实体,在这种情况下您将不会保存任何更改:

      def save(self, *args, **kwargs):
          if self.id is None:
              super(ModelName, self).save(*args, **kwargs)
      

      因此,在此示例中,您仅在实体尚未获得 id 时保存更改,仅当它是尚未插入的新实体时才会出现这种情况。

      【讨论】:

      • 不正确。表中不存在的非None ID 也将是新记录。
      • @Ignacio:我认为你是对的。有人可以在保存实体之前设置 id 属性,在这种情况下 id 不是 None。
      • 你可以使用if not self.id:。毕竟是 python :) 或者:if self.id: raise NotImplementedError("Editing not allowed")
      • @lazerscience:是的,这是一个选项,但我试图不对数据库进行额外调用,只是为了检查 id 是否已经存在。
      • @vdboor:但是使用这个模型的人可能已经在创建实例时在代码中设置了 id。在这种情况下,即使 id 是唯一的,它也不会被保存。
      猜你喜欢
      • 2012-08-22
      • 2018-06-12
      • 2015-11-21
      • 2011-09-16
      • 2011-12-16
      • 2010-10-02
      • 2020-07-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多