I’ve created a Django/Tastypie application where multiple people could possibly be changing attributes of a row in the database at the exact same time or possibly PUT data which is stale.
For instance:
# 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()
Now let’s say any number of users could change the name or description of the Thing at any point in time. They could do it at the same time, or someone could leave the application open for a long time and come back and change it then.
What I’m trying to avoid is latent changes that are incorrect. Given the following situation:
#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"
After line #4, the state of Thing #1 should be name = "some other name", description = "something" instead of name = "some other name", description = "my description".
Assuming the application does not know (in real time or via regularly updating the data on the page) ahead of time that the object on the server has changed, how can this situation be prevented?
I’ve considered adding a field sequence = models.PositiveIntegerField() in which I increment it every time an update is made and so I can tell if the object is out of date when the update happens, but is that the best way? Is there a better way? This seems like it would be a common pattern, right?
The RESTful way to do it is to have the client keep track of either the Last-Modified header or the Etag header returned with the resource. Then, when it POSTs, add a header like
or
If the resource has been modified on the server since the client originally downloaded it, then the server should return a “Precondition Failed” response. The client can then retrieve the current version and display something sensible to the user.
Getting tastypie to respond to those headers, though, might be a bit more difficult.