阻止Django插入或更新SQL Server计算列

时间:2014-12-04 17:19:35

标签: python sql-server django

我有一个看起来像这样的Django模型:

class LocationMaster(models.Model):
    id = models.AutoField(primary_key=True)
    open_date = models.DateField(blank=True, null=True)
    months_open = models.DecimalField(max_digits=18, decimal_places=2, blank=True, null=True) # Calculated column in SQL Server
    maturity = models.CharField(max_length=50, blank=True) # Calculated column in SQL Server

    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        # ?? Something here
        super(LocationMaster, self).save(force_insert, force_update, using, update_field)

我的两个列是SQL Server计算列。我想在我的应用程序中显示这些列,包括在管理员中,但不会插入或更新这些列,因为它们是计算的。如果没有修改我的模型,我会收到此错误:

('42000', '[42000] [FreeTDS][SQL Server]The column "months_open" cannot be modified because it is either a computed column or is the result of a UNION operator. (271) (SQLExecDirectW)')

如何修改模型以便Django不会尝试插入或更新这些特定的列?

3 个答案:

答案 0 :(得分:2)

我在save方法中使用了这个工作来忽略计算的SQL Server列。在此处找到:Prevent Django from updating identity column in MSSQL

def save(self, force_insert=False, force_update=False, using=None,
         update_fields=None):
    # Hack to not save the maturity and months_open as they are computed columns
    self._meta.local_fields = [f for f in self._meta.local_fields if f.name not in ('maturity', 'months_open')]
    super(LocationMaster, self).save(force_insert, force_update, using, update_fields)

答案 1 :(得分:0)

当使用PostgreSQL触发器更新字段时遇到此问题,但django会覆盖它的值(在同一事务中)。

这是一个通用的类装饰器,可以防止将enabled=False字段发送到数据库(可能在任何查询中,如UPDATE)。

def prevent_updating_non_editable_fields(clazz):
      """ prevents sending non`editable` fields in queries  """
      meta = clazz._meta
      meta.local_concrete_fields = [f for f in meta.local_concrete_fields if f.editable]
      return clazz


@prevent_updating_editable_fields
class MyModel(models.Model):
       precomputed = models.IntegerField(default=0, editable=False)

答案 2 :(得分:-1)

您应该可以通过向字段添加editable=False来完成此操作。

此处有更多信息:https://docs.djangoproject.com/en/dev/ref/models/fields/#editable