Django 模型的属性:检查生产系统上的用法
Attribute of a Django Model: Check for Usages on Production Systems
背景
假设我有一个这样的模型:
class Foo(models.Model):
...
name=models.CharField(max_length=1024)
我想:
- 弃用
name
并更新所有 Python 使用它的代码。
- 删除属性
我的猜测:grep 和 PyCharm 只会在代码中找到 98% 的用法,因为 "name" 在很多其他地方使用。
问题
我想检测代码是否在使用此属性的生产系统上执行。可能是这样的:
OtherModel.objects.filter(foo__name=...)
如果 Model.objects.filter() 调用使用此属性,是否有办法记录 DeprecationWarning?
然后我可以安装记录警告的新代码。如果我在大约 8 周内没有看到任何警告,我可以确定如果我删除该属性不会损坏任何重要部件。
我认为在 Python/Django 水平上这样做会非常痛苦,而且几乎不可能确保涵盖所有情况。
最好将这两个字段都保留一段时间,然后使用 SQL 触发器来:
- 保持同步
- 访问已弃用的字段时发出警告
单元测试
这是单元测试为您付出的努力回报 10 倍的时候。如果您的代码覆盖率很高,请继续删除该字段。然后 运行 单元测试。它会快速显示您必须更改哪些代码行。
使用属性。
不如使用单元测试。不适用于 Foo.models.filter() 但在您访问模型实例中的字段时适用于实例。
class Foo(models.Model):
...
_name=models.CharField(max_length=1024)
@property
def name(self):
traceback.print_stack()
return self._name
@name.setter
def name(self, value):
traceback.print_stack()
self._name = value
背景
假设我有一个这样的模型:
class Foo(models.Model):
...
name=models.CharField(max_length=1024)
我想:
- 弃用
name
并更新所有 Python 使用它的代码。 - 删除属性
我的猜测:grep 和 PyCharm 只会在代码中找到 98% 的用法,因为 "name" 在很多其他地方使用。
问题
我想检测代码是否在使用此属性的生产系统上执行。可能是这样的:
OtherModel.objects.filter(foo__name=...)
如果 Model.objects.filter() 调用使用此属性,是否有办法记录 DeprecationWarning?
然后我可以安装记录警告的新代码。如果我在大约 8 周内没有看到任何警告,我可以确定如果我删除该属性不会损坏任何重要部件。
我认为在 Python/Django 水平上这样做会非常痛苦,而且几乎不可能确保涵盖所有情况。
最好将这两个字段都保留一段时间,然后使用 SQL 触发器来:
- 保持同步
- 访问已弃用的字段时发出警告
单元测试
这是单元测试为您付出的努力回报 10 倍的时候。如果您的代码覆盖率很高,请继续删除该字段。然后 运行 单元测试。它会快速显示您必须更改哪些代码行。
使用属性。
不如使用单元测试。不适用于 Foo.models.filter() 但在您访问模型实例中的字段时适用于实例。
class Foo(models.Model):
...
_name=models.CharField(max_length=1024)
@property
def name(self):
traceback.print_stack()
return self._name
@name.setter
def name(self, value):
traceback.print_stack()
self._name = value