我正在建立一个云系统,我有两个应用程序, 包含完整功能的服务器应用程序和仅包含输入法的客户端应用程序, 所以我在客户分支中安装客户端应用程序作为本地应用程序,
我希望在本地保存模型后覆盖应用程序中的任何模型,我将调用芹菜任务将此模型添加到队列中以确保它将到达,即使互联网已关闭,我将重试直到互联网正在起床,
现在我希望最佳实践能够以通用的方式对任何模型进行操作
我有两个选项
1-覆盖这样的保存方法
def save(self, *args, **kwargs):
super(Model, self).save(*args, **kwargs)
save_task.delay(self)
或使用像这样的信号
post_save.connect(save-task.delay, sender=Model)
哪一个是最佳实践,我可以为该项目的所有模型制作泛型?
答案 0 :(得分:7)
.save()
只是一堆一个接一个地执行的信号。这是来自the documentation的过程的缩短版本:
发出保存前信号。 [...]
预处理数据。 [...]大多数字段不进行预处理[...]仅用于具有特殊行为的字段[...] 文档还没有包含所有字段的列表 “特殊行为。”
准备数据库的数据。要求每个字段以可写入数据的数据类型提供其当前值。 数据库。大多数字段不需要数据准备[...]整数和字符串 '准备写'作为Python对象[...]复杂的数据类型经常 需要一些修改。 [...]
将数据插入数据库。 [...]
- 醇>
发出保存后信号。 [...]
在您的情况下,您在该过程中间没有做任何事情。您只需在保存模型后执行此操作。所以不需要使用信号。
现在您要问的是如何确保最终执行任务。良好:
但,如果您真的认为互联网出现故障的可能性很大,或者您确定没有更好的方式来关联您的应用,我建议您添加一个跟踪已更新内容的新模型。像这样:
class Track(models.Model):
modelname = models.CharField(max_length=20)
f_pk = models.IntegerField()
sent = models.BooleanField()
def get_obj(self):
try:
# we want to do modelname.objects.get(pk=self.f_pk), so:
return getattr( getattr(self.modelname, 'objects'), 'get')(pk=self.f_pk)
except:
return False
请注意我并没有将它链接到某个模型,而是给它提供工具来获取你该死的任何模型。然后,对于要跟踪的每个模型,添加以下内容:
class myModel(models.Model):
...
def save(self, *args, **kwargs):
super(Model, self).save(*args, **kwargs)
t = Track(modelname=self.__class__.__name__, f_pk=self.pk, sent=False)
t.save()
然后安排一个Track
对象sent=False
并尝试保存它们的任务:
unsent = Track.objects.filter(sent=False)
for t in unsent:
obj = t.get_obj()
# check if this object exists on the server too
# if so:
t.sent = True
t.save()
<强> P.S。强>
记得我提到的事情会变得难看吗?自从我发布这个以来,我已经看到了。请注意我如何使用pk和modelname来确定是否在两个地方都保存了模型,对吧? 但是,pk是(默认情况下在django中)自动递增的字段。如果应用程序在两个地方运行,或者即使你在本地运行它并且发生了一次错误,那么pks很快就会失去同步。假设我保存了一次对象,它在本地和服务器上都获得了1的pk。
local server
name pk ++ name pk
obj1 1 ++ obj1 1
然后我保存另一个,但互联网发生故障。
local server
name pk ++ name pk
obj1 1 ++ obj1 1
obj2 2 ++
下次启动时,我会添加一个新对象,但这会在调度任务运行之前发生。所以现在我的本地数据库有3个对象,我的服务器有2个,那些有不同的pk,得到它?
local server
name pk ++ name pk
obj1 1 ++ obj1 1
obj2 2 ++ obj3 2
obj3 3 ++
并且在调度任务运行之后我们将拥有:
local server
name pk ++ name pk
obj1 1 ++ obj1 1
obj2 2 ++ obj3 2
obj3 3 ++ obj2 3
看看这有多容易失控?要解决此问题,每个跟踪的模型将 拥有某种唯一标识符,您需要以某种方式告诉Track
模型如何遵循它。这很头疼。最好不要在本地保存东西,而是将所有东西连在一起