如何在django admin中创建一个自动填充和自动递增字段

Osc*_*lal 17 python django django-models default-value django-admin

[ 更新:更改问题标题更具体]

对不起,如果我没有很好地提出问题,我无法想象如何做到这一点:

class WhatEver():
    number = model.IntegerField('Just a Field', default=callablefunction)
...
Run Code Online (Sandbox Code Playgroud)

callablefunction这个查询在哪里:

from myproject.app.models import WhatEver

def callablefunction():
    no = WhatEver.objects.count()
    return no + 1
Run Code Online (Sandbox Code Playgroud)

我想自动写下一个号码,我不知道怎么做.

callablefunction说它无法导入模型时出错,我认为必须有一种更简单的方法来执行此操作.甚至没有必要使用它,但我无法用pk编号来计算如何使用它.

我已经google了这个,我发现的唯一的事情是使用save()方法自动递增数字...但我想<textfield>在保存之前显示它...

你会怎么做?

Osc*_*lal 23

得到它了!我希望这能帮助每个在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 ...]
Run Code Online (Sandbox Code Playgroud)

注意:

  • number函数不带任何参数(甚至不是自己的)
  • 它是在模型中的所有内容之前编写的
  • 这是在django 1.2.1上测试的

此功能将自动clientcode使用下一个数字填充该字段(即如果您有132个客户端,当您添加下一个客户端时,该字段将填充clientcode数字133)

我知道这对于大多数实际情况来说都是荒谬的,因为PK号也是自动递增的,但是在django admin中没有办法自动填充或实际使用它.

[更新:正如我在评论中所述,有一种方法可以使用主键,但保存之前不会填写字段]

  • 你永远不能从这张表中删除任何东西,对吗?否则你会得到重复的代码. (14认同)
  • 考虑使用`Cliente.objects.aggregate(Max('clientcode'))`而不是`Cliente.objects.count()`.这样您就可以避免重复值问题. (8认同)
  • 您确定此代码也适用于并发事务吗?当两个请求同时执行`count()`并稍后写入相同的值时会发生什么? (5认同)
  • 还可以考虑使用 `select_for_update` 来防止并发请求出错。 (2认同)

Yuv*_*dam 8

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

id = models.AutoField(primary_key=True)
Run Code Online (Sandbox Code Playgroud)

您似乎正在尝试复制已存在的行为,只需使用对象主键.

  • 如果必须,只需添加另一个字段,即"AutoField",但不是主键.无论如何,听起来你做错了什么. (2认同)
  • 您的模型中不能使用没有primary_key = True标志的AutoField. (2认同)

Jac*_*nta 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)
Run Code Online (Sandbox Code Playgroud)

以上可能导致几个问题:假设有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)
Run Code Online (Sandbox Code Playgroud)

PS:

你抛出了几次你希望这个字段填写" 之前 ".我想你想在保存之前填写它以便你可以访问它.我要说的是:这种方法允许您访问store.customer_number以查看下一个数字.

  • 我制作的方法就像自动增量那样,它不会重复使用数字.你可以编写一个循环来更新数字,但它可能不值得[你]编写该函数的时间,并且不值得[计算机]时间来运行它.即使是一个小型数据库,打击所有这些记录的时间也可能很长. (2认同)