我有一个模型可以ping一个REST服务并保存结果。
class StoreStatus(models.Model):
store = models.OneToOneField(Store)
status = models.TextField()
def save(self, *args, **kwargs):
self.status = get_store_information(self.store.code)
self.pk = self.store.pk
super( StoreStatus, self ).save(*args, **kwargs)
我需要反复运行它,并且在视图中我可以只是.save()它,因为“Store”对象在我的大多数视图中。
有更好的方法吗?我不得不手动设置pk,因为当我第二次尝试保存时,我遇到了重复错误。
看起来很脏,我正在努力改进我的编码。 感谢
答案 0 :(得分:1)
看起来很糟糕。
首先,将状态信息的检索与保存对象相关联是一个非常糟糕的主意。如果'更新'是您在此模型上执行的唯一操作,那么可能更好的想法是编写一个“update()”方法,一旦状态更新就会自动保存,而不是以其他方式执行周围。
def update(self):
self.status = get_store_information(self.store.code)
self.save()
第二:你是如何创建这个模型的第一个实例的?如果每次模型更新时尝试保存新实例,都会出现重复错误。比方说,如果你这样做:
# this will crap out
update = Update(mystore)
update.save()
你应该做的是:
# this will work (provided we have 'update')
mystore.status.update()
或者:
# always retrieve the stored instance before saving
status, created = StoreStatus.objects.get_or_create(store=mystore)
status.update()
如果您足够懒,您可以随时向Store模型添加“update_status”方法,并在那里执行创建/更新。明确你正在做的事情总是更好。请记住:Django基于最少惊喜的原则,您的代码也应如此! :)
答案 1 :(得分:1)
如果我是你,我会创建一个功能:
1.接受Store对象作为参数,
2.进行REST呼叫,然后执行
3.收到响应后,再更新StoreStatus中的状态。
这对于实现涉及基于Web的服务的体系结构所需的松散耦合是可取的。
此外,如果您只是想避免重复的PK错误,可以检查id以安全地循环更新并创建条件。
def save(self, *args, **kwargs):
if self.id:
# Update case
pass
else:
# New object
# Process for the new object
pass
# Save the changes
super(StoreStatus, self).save(*args, **kwargs)