Python Django模型:多次调用字段的默认方法

Python Django模型:多次调用字段的默认方法,python,django,django-models,django-orm,Python,Django,Django Models,Django Orm,我有以下两个模型(仅用于测试): 现在,我使用普通的Django管理站点创建一个新的测试数据集元素。我所期望的(这里可能我错了)是,在将新数据集保存到数据库时,方法Generator.get_id()只被调用一次。但是真正发生的是,Generator.get\u id()方法被调用了三次: 第一次单击管理区域中的“添加测试数据集”按钮时 之后不久的第二次(没有来自用户端的额外交互) 第三次是在最后保存新数据集时 第一次可以:这是表单字段中预先填充的值。由于主键字段未显示在我的表单中,因此这可

我有以下两个模型(仅用于测试):

现在,我使用普通的Django管理站点创建一个新的测试数据集元素。我所期望的(这里可能我错了)是,在将新数据集保存到数据库时,方法
Generator.get_id()
只被调用一次。但是真正发生的是,
Generator.get\u id()
方法被调用了三次:

  • 第一次单击管理区域中的“添加测试数据集”按钮时
  • 之后不久的第二次(没有来自用户端的额外交互)
  • 第三次是在最后保存新数据集时
第一次可以:这是表单字段中预先填充的值。由于主键字段未显示在我的表单中,因此这可能是一个不必要的调用

第三次也很清楚:这是在保存之前完成的。在真正需要的时候

上面的代码只是一个示例,对我来说是一个测试。在实际项目中,我必须向远程系统请求一个ID,而不是从另一个表模型。但每当我查询该系统时,传递的ID就会被锁定在那里,就像
get\u ID\u for\u table()
方法一样

我相信只有在插入新数据集时,才有更好的方法在真正需要时从方法中获取ID——该方法应该只调用一次。你知道怎么做到吗

忘记了版本:它是Python3.4上的Django 1.8.5。

这不是您问题的答案,但可能是您问题的解决方案


我认为这个问题很复杂。特别是因为您需要一个跨webservice调用和数据库插入的事务。。。在本例中,我将使用:在本地生成uuid。实际上,该值在4d世界(时间+位置)中是唯一的,并将其用作id。稍后,保存完成后,与远程服务同步。

这不是原子(
save()
),当您意识到自己的id重复时,您将处于一个受伤的世界。DB再次自动编号有什么问题?这只是一个测试示例。在实际项目中,我从远程服务获取ID。当然,这项服务只提供一次每个ID。但是我需要确保调用该服务的方法对于一个新数据集只调用一次。过去我遇到过这样的问题,
发出信号
调用我的代码两次,调试起来有点困难,但不用担心。PDB用于救援,或
ipdb
更好
pip安装ipdb
然后在
get\u id\u for_table()
add
import ipdb;ipdb.set_trace()
然后查看您的控制台并等待中断,键入
where
,您将看到它是如何被调用的,以及为什么被调用的。您是Java程序员吗?这并不是你写Python的方式。事实上,这是我目前计划B的一部分。
class IdGeneratorModel(models.Model):

    table = models.CharField(primary_key=True, unique=True,
                             null=False, max_length=32)
    last_created_id = models.BigIntegerField(default=0, null=False,
                                             unique=False)

    @staticmethod
    def get_id_for_table(table: str) -> int:
        try:
            last_id_set = IdGeneratorModel.objects.get(table=table)
            new_id = last_id_set.last_created_id + 1
            last_id_set.last_created_id = new_id
            last_id_set.save()
            return new_id
        except IdGeneratorModel.DoesNotExist:
            np = IdGeneratorModel()
            np.table = table
            np.save()
            return IdGeneratorModel.get_id_for_table(table)

class TestDataModel(models.Model):

    class Generator:
        @staticmethod
        def get_id():
            return IdGeneratorModel.get_id_for_table('TestDataModel')

    id = models.BigIntegerField(null=False, primary_key=True,
                                editable=False, auto_created=True,
                                default=Generator.get_id)
    data = models.CharField(max_length=16)