3

我创建了一个 Django/Tastypie 应用程序,其中多个人可能同时更改数据库中一行的属性,或者可能 PUT 数据是陈旧的。

例如:

 # the Django model
 class Thing(models.Model):
      name = models.CharField(max_length=100)
      description = models.TextField()

 # the Tastypie Resource
 class ThingResource(ModelResource):
       class Meta:
           queryset = Thing.objects.all()

现在假设任意数量的用户可以在任何时间点更改name或。他们可以同时进行,或者有人可以将应用程序打开很长时间,然后再回来更改它。descriptionThing

我试图避免的是不正确的潜在变化。鉴于以下情况:

#1 User 1: Opens app viewing Thing #1 with name = "my name", description = "my description"
#2 User 2: Opens app viewing Thing #1 (same state as User 1)
#3 User 2: Changes description of Thing #1 to "something"
#4 User 1: Changes name of Thing #1 to "some other name"

在行之后#4,Thing #1 的状态应该是name = "some other name", description = "something"而不是name = "some other name", description = "my description"

假设应用程序不提前知道(实时或通过定期更新页面上的数据)服务器上的对象已更改,如何防止这种情况发生?

我考虑过添加一个字段sequence = models.PositiveIntegerField(),每次更新时我都会在其中增加它,这样我就可以在更新发生时判断对象是否已过期,但这是最好的方法吗?有没有更好的办法?这似乎是一种常见的模式,对吧?

4

2 回答 2

4

使用 REST,资源的状态由服务器管理,因此您对序列字段的想法是正确的。服务器跟踪资源所在的版本,客户端在发送新版本时说它认为它正在创建的版本。如果客户端弄错了,服务器会告诉它。

Ian 对 ETag 或修改日期的建议听起来是正确的做法,并且对类似问题的回答也同意。我自己实际上并没有太多这方面的经验。

于 2012-01-09T22:33:47.913 回答
3

RESTful 方法是让客户端跟踪资源返回的 Last-Modified 标头或 Etag 标头。然后,当它发布时,添加一个标题,如

If-Unmodified-Since: <date-noted-from-initial-GET>

或者

If-Match: <etag-noted-from-initial-GET>

如果资源在客户端最初下载后在服务器上被修改过,那么服务器应该返回一个“Precondition Failed”响应。然后,客户端可以检索当前版本并显示对用户有意义的内容。

不过,让美味派响应这些标题可能会更困难一些。

于 2012-01-09T23:46:04.880 回答