有什么办法在django中做这样的事情吗?线程安全字段值计数
INSERT INTO t VALUES(1,(SELECT x.c2 FROM t x ORDER BY c2 DESC LIMIT 1)+1,1);
我有一个很多领域的模型。而且其中一个字段的值必须根据之前的记录进行设置。
目前我正在通过简单的选择上一条记录来做到这一点。但这是可怕的,而不是线程安全的。
def save(self, *args, **kw):
if self.sn is None or self.sn == ns.DEFAULT_GIFT_SN:
q = Gift.objects.filter(company = self.company).only('id').order_by('-id')
if q.count():
last = q[0]
next_id = int(last.sn) + 1
else:
next_id = 1
self.sn = next_id
super(Gift, self).save(*args, **kw)
我想要。懒像:
def save(self, *args, **kw):
if self.sn is None or self.sn == ns.DEFAULT_GIFT_SN:
self.sn = _F('SELECT x.c2 FROM t x ORDER BY c2 DESC LIMIT 1')
super(Gift, self).save(*args, **kw)
有什么建议吗?
UPDATE(塞萨尔):
class Gift(models.Model):
company = models.ForeignKey(Company)
certificate = ChainedForeignKey(Certificate,
chained_field = "company",
chained_model_field = "company",
show_all = False,
auto_choose = True
)
gifter = models.ForeignKey(User, null = True, blank = True)
giftant_first_name = models.CharField(_('first name'), max_length = 30, blank = True)
giftant_last_name = models.CharField(_('last name'), max_length = 30, blank = True)
giftant_email = models.EmailField(_('e-mail address'), blank = True)
giftant_mobile = models.CharField(max_length = 20, blank = True, null = True)
due_date = models.DateTimeField()
exp_date = models.DateTimeField()
sn = models.CharField(max_length = 32, default = ns.DEFAULT_GIFT_SN, editable = False)
pin_salt = models.CharField(max_length = 5, editable = False, default = gen_salt)
pin = models.CharField(max_length = 32, null = True, blank = True)
postcard = models.ForeignKey(Postcard)
state_status = models.IntegerField(choices = ns.STATE_STATUSES, default = ns.READY_STATE_STATUS)
delivery_status = models.IntegerField(choices = ns.DELIVERY_STATUSES, default = ns.WAITING_DELIVERY_STATUS)
payment_status = models.IntegerField(choices = ns.PAYMENT_STATUSES, default = ns.NOT_PAID_PAYMENT_STATUS)
usage_status = models.IntegerField(choices = ns.USAGE_STATUSES, default = ns.NOT_USED_USAGE_STATUS)
nominal = models.FloatField(default = 0)
used_money = models.FloatField(default = 0)
use_date = models.DateTimeField(blank = True, null = True)
pub_date = models.DateTimeField(auto_now_add = True)
cashier = ChainedForeignKey(CompanyUserProfile, blank = True, null = True,
chained_field = "company",
chained_model_field = "company",
show_all = False,
auto_choose = True
)
class Meta:
unique_together = ('company', 'sn',)
你能展示你的模型吗? –
为什么不为'sn'属性设置默认值1,并在礼品ID上返回一个MAX,由公司过滤?如果MAX id> 1,则将其增加1.然后,您将返回标量值而不是保湿对象。 – Brandon
@Brandon我同意你的想法,这会更好。但是这并没有解决线程安全的问题。如果两个线程将同时选择最大值而不是更新。他们两人将具有相同的价值。实际上,这可以通过锁定来解决,但我认为能够在查询时更新值会更好。 –