Django模型真的需要一个唯一的关键字段

时间:2013-12-30 02:42:15

标签: django django-models foreign-keys

我的部分models仅在keys的组合中是唯一的。我不想使用auto-numbering id作为标识符,因为数据的子集将导出到其他系统(例如spreadsheets),已修改,然后用于更新{ {1}}。

以下是一个例子:

master database

class Statement(models.Model): supplier = models.ForeignKey(Supplier) total = models.DecimalField("statement total", max_digits=10, decimal_places=2) statement_date = models.DateField("statement date") .... class Invoice(models.Model): supplier = models.ForeignKey(Supplier) amount = models.DecimalField("invoice total", max_digits=10, decimal_places=2) invoice_date = models.DateField("date of invoice") statement = models.ForeignKey(Statement, blank=True, null=True) .... 条记录仅适用于Invoicesupplieramount

的组合

我想知道我是否应该根据invoice_dateslugInvoicesupplier创建amount,以便很容易识别正确的记录。

让多个invoice_date识别正确记录的问题的一个示例是related fields,它假设只有一个相关字段,并且在构建django-csvimport时不会区分两个字段。

然而,foreign key links似乎是一个笨拙的选择,需要某种管理来在批量添加slug后重建slugs

我认为这一定是一个常见问题,也许某处有最佳实践设计模式。

如果有人拥有数据库解决方案,我正在使用records。虽然我希望尽可能避免这种情况,但我可以看到,如果可以使用PostgreSQL,那么可能是构建我的slug的方法。这只是感觉有点像隐藏的功能,并可能导致设置在不同的服务器上的头痛。

更新 - 阅读初步回复后

我的应用程序要求在审核和批准后可以远程导出,修改数据并将其合并回主数据库。隐藏的自动编号键不能轻易地存活下来。如果trigger functions表已从invoices[2417] is part of statements[265]清空并重新加载,则statement关系不会持久。

如果我使用数字自动编号CSV,则更新pk的任何进程都需要刷新相关的键编号或使用多个WITH子句。

如果我创建一个基于我的3个键但很容易重现的slug,那么我可以用它作为键 - 尽管很笨拙。我正想着一条线:

database

这看起来很笨拙而且不是u'%s %s %s' % (self.supplier, self.statement_date.strftime("%Y-%m-%d"), self.total) 因为我预计我可能不得不在其他地方重新创建一个重复算法的slug(可能在DRY公式或Excel查询中)< / p>

我认为必须有一种更好的方式让我失踪,但看起来yuvi的回复意味着应该有,而且会有,但还没有: - (

2 个答案:

答案 0 :(得分:2)

您所说的是多列主键,也称为"composite" or "compound" keys。今天django对复合键的支持仍在开发中,你可以阅读它here

  

目前Django模型仅支持此集合中的单个列,   否认许多设计,其中表的自然主键是   多列[...]当前状态是问题所在   接受/分配和工作[...]

该链接还提到了django-compositekeys的部分实现。它只是部分的,会导致你在关系之间导航时遇到麻烦:

  ForeignKey中缺少对复合键的支持   RelatedManager。因此,无法导航   来自具有复合主键的模型的关系。

所以目前它并不完全支持,但将来会有所支持。关于你自己的项目,你可以做到你想要的,虽然我自己的建议是坚持一个你甚至不需要考虑的隐藏的自动增量字段的完全支持的默认值(并使用{{3}强制执行所描述字段的uniqness而不是将它们作为主键。

我希望这有帮助!

答案 1 :(得分:1)

没有

模型需要有一个primary_key = True的字段。默认情况下,这是存储对象Id的(隐藏)自动字段。但您可以在任何其他字段将primary_key设置为True。 我已经在以下情况下完成了这项工作:我在以前手动或通过其他一些框架/系统创建的表格上创建django项目。

实际上 - 您可以使用您能想到的任何方法,在查询中将对象连接在一起。只要查询返回可以与您拥有的模型关联的一堆数据 - 用于连接的字段并不重要。请记住,您使用的解决方案应该尽可能有效。

艾伦