Django atomic update based on filter result
I've got a model that looks like
class order(models.Model):
user = models.ForeignKey(some_user)
number = models.PositiveIntegerField()
number is supposed to be an incremented (+1) amount based on the total number of开发者_StackOverflow社区 existing orders for a user. I've looked into F() objects before but from what I can gather they can only be used for updating a field thats pre-existing. Is there a way to increment that the number by 1 without having a to worry about two orders have the same number?
I think what you are trying to do is to get the total number of orders per user. Then it'll be better for you to first create a many to many field between user
and order
. Then you can get the count required by simply instantiating a given user(say userone
) and then calling,
userone.order_set.count()
What you are looking for is how to create a sequence for each user. You can use a database sequence (postgres) or something like this:
class UserMetadata(models.Model):
user = models.OneToOneField(User)
next_order_number = models.PositiveIntegerField(default=1)
And each time you create a new order you use the next_order_number
field and increment it by one (using UPDATE ... LAST_INSERT_ID(next_order_number+1)...
in MySQL. See: AutoIncrement fields on databases without autoincrement field ).
As far as I know Django have no built in support for creating such sequences in an atomic way. This might be a good start: http://djangosnippets.org/snippets/304/
If it was about just incrementation of number, then using a AutoField might be enough, but incrementation of a value prior to some other data is not easy to handle on model definiton.
One possible way is overriding save() method.
Check here for basic django saving procedure. And here for how to override default save method. You may try to check if related save action is for a new insertion or an update for an existing record, and if it is insertion, you may set a unique number to that record for specified user.
Seeing as Django doesn't support creating atomic sequences, my conclusion is to use Redis for atomic counting and just query that in order to get the latest order value.
精彩评论