Django自动增量字段

发布于 2025-02-11 20:38:53 字数 229 浏览 1 评论 0原文

我有2列名为串行和包的列,我需要自动增加它们,但彼此相互汇总,也基于将更新记录的用户,因此每个袋子都应具有100个序列号并在达到100后自动重置数字,然后开始再次使用2号袋,然后将100个序列放在其中并重置。

例如:

当用户更新第一个记录时,袋子将从数字1开始,串行也将是数字1,第二个记录袋仍将数字1,串行将更改为2号,直到在一个袋中达到100串行,然后我们将从第2号行李和序列号1等开始...

谢谢

I have 2 columns named Serial and Bag I need them to be auto incremented but based on each other and also based on the user that will update the record, so every bag should have 100 serial and reset the number automatically after reaching 100, then start again with Bag number 2 and put 100 serial in it and reset.

For example:

when user update the first record the Bag will start with number 1 and Serial will be also number 1 the second record Bag will still number 1 and the serial will be changed to number 2 till reach 100 Serial in one Bag, then we will start again with bag number 2 and serial number 1 etc ...

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

窗影残 2025-02-18 20:38:53

您解释示例的方式有些混乱,但我会尝试给您一个答案。

我假设“ 2列”名为serial and bag 是同一模型的字段,正如您在评论中回答的“ 记录已经存在,但它具有空的串行和袋子“,这意味着自动报道在更新记录时开始。最后,您提到了第一个和第二个记录,暗示该模型中有多个记录。基于这些标准,您可以做的就是在模型中添加一个保存方法:

# Sample model
class Record(models.Model):
  bag = models.IntegerField(default=0, null=True)
  serial = models.IntegerField(default=0, null=True)
  created_at = models.DateTimeField(auto_now=True, null=True)

  def save(self, *args, **kwargs):
    # Ensures the record will only auto-increment during update
    if self.created_at:
      # Retrieves the object with the highest bag & serial value
      latest_record = Record.objects.all().order_by('bag', 'serial').last()

      # Incrementing logic
      if latest_record.serial_no + 1 <= 100:
        self.bag = latest_record.bag if latest_record.bag > 0 else 1
        self.serial = latest_record.serial + 1
      else:
        self.bag = latest_record.bag + 1
        self.serial = 1

    super(Record, self).save(*args, **kwargs)

现在,每次写入保存时,例如:

record = Record()
record.save()

模型保存方法执行。

The way you explain your example is a bit confusing but I'll try to give you an answer.

I assume the "2 columns named Serial and Bag" are fields of the same model and as you replied in the comments "the record is already existing but it has empty serial and bag", which means the auto-increment begins when the record is updated. Lastly, you mentioned first and second records implying that there are multiple records in this model. Based on these criteria, what you can do is add a save method in your model:

# Sample model
class Record(models.Model):
  bag = models.IntegerField(default=0, null=True)
  serial = models.IntegerField(default=0, null=True)
  created_at = models.DateTimeField(auto_now=True, null=True)

  def save(self, *args, **kwargs):
    # Ensures the record will only auto-increment during update
    if self.created_at:
      # Retrieves the object with the highest bag & serial value
      latest_record = Record.objects.all().order_by('bag', 'serial').last()

      # Incrementing logic
      if latest_record.serial_no + 1 <= 100:
        self.bag = latest_record.bag if latest_record.bag > 0 else 1
        self.serial = latest_record.serial + 1
      else:
        self.bag = latest_record.bag + 1
        self.serial = 1

    super(Record, self).save(*args, **kwargs)

Now, each time you write save like:

record = Record()
record.save()

The model save method executes.

千纸鹤 2025-02-18 20:38:53

与其进行python中的逻辑,如果可以同时进行多个更新,则应将其推到数据库中。

类似:


update foop set
  bag=vala,
  ser=valb 
from (
    select 
       case when ser >= 5 then bag+1 else bag end as vala,
       case when ser >= 5 then 1 else ser+1 end as valb 
    from foop
    order by bag desc nulls last,
       ser desc nulls last
    limit 1) as tt
where some_primarykey = %;

可能可以将其转换为django orm,但是仅掉入RAW SQL或通过.extra()在QuerySet上试图将其插入。

Rather than do the incrementing logic in python, where it is subject to race conditions if multiple updates can happen concurrently, it should be possible to push it down into the database.

Something like:


update foop set
  bag=vala,
  ser=valb 
from (
    select 
       case when ser >= 5 then bag+1 else bag end as vala,
       case when ser >= 5 then 1 else ser+1 end as valb 
    from foop
    order by bag desc nulls last,
       ser desc nulls last
    limit 1) as tt
where some_primarykey = %;

It might be possible to translate that into django ORM, but it might also be easier and more readable to just drop into raw SQL or sneak it in via .extra() on a queryset than attempt to shoehorn it in.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文