Django的模型节省流量

时间:2013-10-20 06:28:22

标签: python ajax django google-app-engine

我注意到在模型上调用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响应。

2 个答案:

答案 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/