如何在Django Admin中创建自动填充和自动递增字段

21 投票
4 回答
35085 浏览
提问于 2025-04-16 00:28

[更新:将问题标题改得更具体一些]

抱歉,如果我没把问题描述清楚,我现在搞不明白该怎么做:

class WhatEver():
    number = model.IntegerField('Just a Field', default=callablefunction)
...

这里的 callablefunction 执行了这个查询:

from myproject.app.models import WhatEver

def callablefunction():
    no = WhatEver.objects.count()
    return no + 1

我想要自动写下一个数字,但我不知道该怎么做。

我在 callablefunction 中遇到了错误,提示它无法导入模型,我觉得应该有更简单的方法来实现这个功能。其实根本不需要使用这个,但我就是搞不清楚怎么用主键(pk)数字来做。

我在网上查过这个,找到的唯一信息是使用 save() 方法来自动递增数字……但我想在保存之前先在 <textfield> 中显示出来……

你会怎么做呢?

4 个回答

6

我也遇到过这个问题,我的情况是关于 customer.number,它和顾客的 Store 有关。我一度想用类似这样的方式:

# Don't do this:

class Customer(models.Model):
    # store = ...
    number = models.IntegerField(default=0)

    def save(self, *args, **kwargs):
        if self.number == 0:
            try:
                self.number = self.store.customer_set.count() + 1
            else:
                self.number = 1
        super(Customer, self).save(*args, **kwargs)

上面的方法可能会引发几个问题:假设有10个顾客,我删除了顾客编号6。下一个添加的顾客看起来会是第10个顾客,这样就会出现第二个顾客#10。(这可能会在 get() 查询中造成很大的错误)

最后我用的是类似这样的方式:

class Store(models.Model):
    customer_number = models.IntegerField(default=1)

class Customer(models.Model):
    store = models.ForeignKey(Store)
    number = models.IntegerField(default=0)

    def save(self, *args, **kwargs):
        if self.number == 0:
            self.number = self.store.customer_number
            self.store.number += 1
            self.store.save()
        super(Customer, self).save(*args, **kwargs)

补充说明:

你多次提到你希望这个字段在“之前”被填充。我想你是希望在保存之前填充,以便你可以访问它。对此我想说:这个方法可以让你访问 store.customer_number,以查看下一个即将到来的编号。

8

每个Django模型都有一个自动生成的主键

id = models.AutoField(primary_key=True)

看起来你是在尝试重复一个已经存在的功能,其实只需要使用对象的主键就可以了。

34

明白了! 希望这能帮助到那些在Django中遇到自动填充和自动递增字段问题的朋友。解决方案是:

class Cliente(models.Model):
    """This is the client data model, it holds all client information. This
       docstring has to be improved."""
    def number():
        no = Cliente.objects.count()
        if no == None:
            return 1
        else:
            return no + 1

    clientcode = models.IntegerField(_('Code'), max_length=6, unique=True, \
    default=number)

    [... here goes the rest of your model ...]

注意事项:

  • number 函数不需要任何参数(连自己都不需要)
  • 它需要在模型中的所有内容之前
  • 这个方法是在Django 1.2.1上测试的

这个函数会自动把clientcode字段填上下一个数字(比如说,如果你有132个客户,当你添加下一个客户时,这个字段会自动填上clientcode数字133)

我知道在大多数实际情况下这听起来有点荒谬,因为主键(PK)数字也是自动递增的,但在Django的管理界面中没有办法自动填充或者实际使用这个功能。

[更新:正如我在评论中提到的,确实有办法使用主键来实现这个功能,但它不会在保存之前填充字段]

撰写回答