假设一个类有一个修改它内部的方法。 该方法应该在返回之前调用自身保存还是应该在调用修改方法后将保存留给调用者显式保存?
示例:
明确地调用save:
class Bar(models.Model):
def set_foo(self, foo):
self.foo = foo
bar = Bar()
bar.set_foo("foobar")
bar.save()
或允许方法调用save:
class Bar(models.Model):
def set_foo(self, foo):
self.foo = foo
self.save()
bar = Bar()
bar.set_foo("foobar")
我正在和django一起工作,但我想知道django或者一般情况下这种情况是否有最好的做法。
答案 0 :(得分:3)
您的API的用户可能希望进行多项更改,在每次更改之后保存对象都是好的,所以不要,不要在方法中调用save。
答案 1 :(得分:2)
您的API用户可能忘记调用.save()然后搞砸了。所以我认为最好为他打电话。对于Daslch提到的案例,如果有意义,你可以定义:
def set_foo(self, foo, skip_save=False):
self.foo = foo
if not skip_save:
self.save()
所以如果用户愿意(并明确说明),用户可以避免保存。
答案 2 :(得分:1)
实际上,我同意Ofri和Daslch ......取决于一周的哪一天。如果这只是您可能对特定对象执行的许多修改例程之一,那么每个修改例程都会自行保存。另一方面,如果这是一个罕见的,自包含的事件,那么你想要进行保存,因为它对调用者来说可能并不明显(即你以外的其他人需要它完成。
例如,标记事件(无论如何都使用ManyToMany)应该不需要程序员部分的额外save()。
答案 3 :(得分:0)
为了处理各种现有答案中表达的所有问题,我建议采用以下方法:制作一个方法,称之为saving
或modifying
,即上下文管理器。该方法的条目设置一个私有标志,表示修改正在进行中;出口重置标志并执行保存;所有修改方法都会检查标志并在未设置时引发异常。例如,使用基类和实际子类必须覆盖的save
方法:
import contextlib
class CarefullyDesigned(object):
def __init__(self):
self.__saving = False
def _save(self):
raise NotImplementedError('Must override `_save`!')
def _checksaving(self):
"Call at start of subclass `save` and modifying-methods"
if not self.__saving: raise ValueError('No saving in progress!')
@contextlib.contextmanager
def saving(self):
if self.__saving: raise ValueError('Saving already in progress!')
self.__saving = True
yield
self._save()
self.__saving = False
使用示例......:
class Bar(models.Model, CarefullyDesigned):
def __init__(self, *a, **k):
models.Model.__init__(self, *a, **k)
CarefullyDesigned.__init__(self)
def _save(self):
self._checksaving()
self.save()
def set_foo(self, foo):
self._checksaving()
self.foo = foo
def set_fie(self, fie):
self._checksaving()
self.fie = fie
bar = Bar()
with bar.saving():
bar.set_foo("foobar")
bar.set_fie("fo fum")
这可以保证用户不会忘记调用saving
,也不会忘记以嵌套的方式调用它(这是所有这些例外的目的),并且当用户组中只调用save
一次修改方法是方便的,我会说,非常自然的方式。