Python 如何强制/警告开发人员对待class/django模型的方式
我们有一个Django项目,今年我多次遇到这个问题 我将简化示例:Python 如何强制/警告开发人员对待class/django模型的方式,python,django,pycharm,Python,Django,Pycharm,我们有一个Django项目,今年我多次遇到这个问题 我将简化示例: class MyModel(Model): my_attr = .... ... def get_my_attr_safe(): if not self.my_attr: return somecalculation() return self.my_attr 我想强制开发人员使用get\u my\u attr\u safe()而不是my\u a
class MyModel(Model):
my_attr = ....
...
def get_my_attr_safe():
if not self.my_attr:
return somecalculation()
return self.my_attr
我想强制开发人员使用get\u my\u attr\u safe()
而不是my\u attr
这是一个巨大而复杂的模型
我的想法是以某种方式重写\uuuu getattribute\uuuu
,并在直接调用时引发异常,但我认为这行不通。此外,Django
,当然有时需要直接调用ModelFields
,所以我不能这样做
我想提出异常
,或者确保他们在可能的情况下获得必须使用方法
的信息
例如,我需要他们在模板中的任何地方使用该方法:
{{ obj.get_my_attr_safe }}
而不是
{{ obj.my_attr }}
解决方案不必是
Python
ic,也许有一种方法可以仅使用PyCharm
来实现这一点。这就足够了。在这里使用下划线可能会有所帮助:
class MyModel(Model):
_my_attr = None
def get_my_attr_safe(self):
if self._my_attr is None:
self._my_attr = somecalculation()
return self._my_attr
my_attr = property(get_my_attr_safe)
摘自我不建议覆盖
\uuu getattr\uuuu
或触摸模型
类中的任何内容。这是Django的核心,如果你做了什么,你可能不知道下一个bug会出现在哪里。与此相反,我认为最好在它周围使用一个包装器来获得限制。例如:
class YourModelWrapper(object):
model_object = None
restricted_fields = ['some', 'fields']
def __init__(self, model_object):
self.model_object = model_object
def __getattr__(self, name):
if name is not in self.restricted_fields:
return getattr(self.model_object, name)
raise AttributeError("Use get_{}_safe() method instead".format(name)
# Usage
your_model_wrapper_obj = YourModelWrapper(YourModel.objects.first())
your_model_wrapper_obj.my_attr # will raise exception
your_model_wrapper_obj.get_my_attr_safe() # will return the values
仅供参考,使用这个而不是实际的模型会很麻烦,因为这个包装器缺少很多东西,比如queryset支持。但也有好的一面。您已经说过,您的模型非常复杂,因此使用包装器可能有助于在不同的模型之间增加一些复杂性,或者像使用服务一样使用它。这似乎与Python的Zen背道而驰。众所周知,Python甚至没有强制的作用域限制,例如
private
、protect
或其他内容。原因是Python相信开发人员能够做正确的事情。因此,对于同一个Zen,我认为你应该为你的用户提供足够的文档,并注意到如果你不以这种方式使用它,将会发生什么等。良好地使用PR review在这里是有帮助的:)在我看来,覆盖\uuuu getattribute\uuuuuuuuu
或任何类型的黑客来实现一些简单的东西似乎太过了。