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

Django模型真的需要一个唯一的键字段吗,django,django-models,foreign-keys,Django,Django Models,Foreign Keys,我的一些型号仅在键组合中是唯一的。我不想使用自动编号id作为标识符,因为数据子集将导出到其他系统(如电子表格),修改后用于更新主数据库 下面是一个例子: class Statement(models.Model): supplier = models.ForeignKey(Supplier) total = models.DecimalField("statement total", max_digits=10, decimal_places=2) statement

我的一些
型号
仅在
键组合中是唯一的。我不想使用
自动编号
id
作为标识符,因为数据子集将导出到其他系统(如
电子表格
),修改后用于更新
主数据库

下面是一个例子:

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)
    ....
发票
记录仅对
供应商
金额
发票日期

我想知道我是否应该根据
供应商
金额
发票日期
发票
创建一个
slug
,以便识别正确的记录

有多个
相关字段
来识别正确记录的问题的一个例子是
django csvimport
,它假设只有一个相关字段,并且在构建
外键链接时不会区分两个

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

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

我正在使用
PostgreSQL
,以防任何人有数据库解决方案。尽管我希望尽可能避免这种情况,但我可以看到,如果这是一种方法,那么它可能是构建我的
slug
的一种方法,可能是使用
触发函数。不过,这感觉有点像隐藏的功能,在不同的服务器上安装可能会让人头疼

更新-阅读初始回复后

我的应用程序要求数据可以导出、远程修改,并在审核和批准后合并回主数据库。隐藏的自动编号键不容易保持一致。如果从
CSV
中清空并重新加载
语句
表,则关系
发票[2417]是语句[265]的一部分
不会持久

如果我使用数字自动编号
pk
,则任何更新
数据库的过程都需要刷新相关的键号或使用multiple WITH子句

如果我创建了一个基于我的3个键但很容易复制的slug,那么我可以使用它作为键-尽管很笨拙。我想到了一只鼻涕虫:

u'%s %s %s' % (self.supplier, 
    self.statement_date.strftime("%Y-%m-%d"), 
    self.total)
这看起来相当笨拙,而且不太干燥,因为我预计我可能不得不在其他地方重新创建slug,复制算法(可能在
Excel
公式中,或者在
Access
查询中)

我想一定有更好的方法让我错过了,但看起来尤维的回答意味着应该有,而且会有,但还没有:-(

没有

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

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


Alan

您正在谈论的是一个多列主键,也称为。django对复合键的支持目前仍在进行中,您可以阅读以下内容:

目前Django型号仅支持此集合中的单个列, 拒绝使用表的自然主键的许多设计 多列[…]当前状态是问题是 已接受/分配并正在工作[…]

该链接还提到了一个部分实现,即。它只是部分实现,会给您在关系之间导航带来麻烦:

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

因此,目前还不完全支持,但将来会支持。关于你自己的项目,你可以随心所欲地使用它,尽管我个人的建议是坚持完全支持的默认值,即隐藏的自动递增字段,你甚至不需要考虑它(并使用以强制所述字段的唯一性,而不是将其作为主键)


我希望这能有所帮助!

我想表达的是,django不会“验证”这种关系——所有这些都发生在数据库中,而您在模型中描述的只是为了让模型“工作”不用于优化实际查询。您如何描述关系以及它们的工作速度仍然只取决于您如何创建表以及如何优化索引。Django layer仅基于从数据库读取的数据创建对象。谢谢。结论令人失望,但至少我没有遗漏一些明显的内容。链接文章ly表达了同样的困境,并提出了一个人工的
散列
选项,但也有相应的缺点。不要失望,我试图表达的观点类似于@OdifYltsaeb-您应该始终这样做,但在这种情况下,我不能在
语句
上设置一个主键,这意味着识别正确的记录需要使用多个条件进行查询
,其中supplier=test.supplier和total=test.total以及statement\u date=test.statement\u date
。我可以将其放入SQL中,但许多Django软件包都假设外键将指向具有可用主键的对象,因此许多可用的自动化操作都会丢失。例如,我正在使用
dja