我注意到在模型上调用save()后无法保证数据库是同步更新的。
我通过对以下方法进行ajax调用来完成一个简单的测试
def save(request, id)
product = ProductModel.objects.find(id = id)
product.name = 'New Product Name'
product.save()
return HTTPResponse('success')
在客户端,我等待上述方法的响应,然后执行检索产品列表的findAll方法。返回的产品列表包含更新产品名称的旧值。
但是,如果我延迟了对产品列表的请求,那么它就会包含新值,就像它应该的那样。
这意味着如果在将新值写入数据库之前触发,则返回HTTPResponse('success')。
如果上述情况属实,那么只有在数据库更新后才能返回HTTP响应。
答案 0 :(得分:4)
你应该更突出地提到App Engine。我已将它添加到标签中。
这绝对是因为你对GAE缺乏了解,而不是与Django有任何关系。您应该阅读eventual consistency in the datastore上的GAE文档,并适当地构建模型和查询。
使用标准关系数据库运行的普通Django不会出现此问题。
答案 1 :(得分:1)
在.save()函数结束其流程之前,视图不应返回任何内容。
至于流本身,Django的文档非常明确地声明:
当您保存对象时,Django会执行以下步骤:
1)发出预保存信号。发送信号django.db.models.signals.pre_save,允许任何侦听该信号的函数采取一些自定义操作。
2)预处理数据。要求对象上的每个字段执行字段可能需要执行的任何自动数据修改。
大多数字段不进行预处理 - 字段数据保持原样。预处理仅用于具有特殊行为的字段。例如,如果模型的DateField具有auto_now = True,则预保存阶段将更改对象中的数据,以确保日期字段包含当前日期戳。 (我们的文档尚未包含具有此“特殊行为”的所有字段的列表。)
3)准备数据库的数据。要求每个字段以可写入数据库的数据类型提供其当前值。
大多数字段无需数据准备。简单的数据类型(如整数和字符串)可以作为Python对象“准备写入”。但是,更复杂的数据类型通常需要进行一些修改。
例如,DateField字段使用Python日期时间对象来存储数据。数据库不存储日期时间对象,因此必须将字段值转换为符合ISO的日期字符串,以便插入数据库。
4)将数据插入数据库。然后将预处理的准备好的数据组合成一个SQL语句,以便插入到数据库中。
5)发出保存后信号。发送信号django.db.models.signals.post_save,允许任何侦听该信号的函数采取一些自定义操作。
请注意,如果您已将@transaction.commit_on_success
装饰器应用于视图,则可能会收到您的行为,但我在您的代码中没有看到它。
有关交易的更多信息:https://docs.djangoproject.com/en/1.5/topics/db/transactions/