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