如何在 Django 中创建一个包含两个字段的主键?
Posted
技术标签:
【中文标题】如何在 Django 中创建一个包含两个字段的主键?【英文标题】:How to create a primary key consists of two fields in Django? 【发布时间】:2015-09-28 06:29:20 【问题描述】:我开发了一个特定的应用程序,我发现它具有指定的数据库和模型架构。我正在使用 Django 1.8.2 版。下面提出一个问题。不必要的字段已被省略,模型名称是为了示例的目的而发明的,因为我不能透露。考虑以下模型 A 和 B。
class B (models.Model):
name = models.CharField(max_length=100)
class A (models.Model):
name = models.CharField(max_length=100, primary_key=True)
related_name = models.ForeignKey(B, null=True, blank=True)
一个项目在很长一段时间后可能会有几个同名的A,但具有不同的外键B。在这种特殊情况下,我想建模主键“A”由两个字段组成:名称和相关名称。 django中如何创建这样一个包含两个字段的key?
【问题讨论】:
是否可以将A
的主键改为django默认的id
?这似乎是显而易见的解决办法。
嗨 :-) 感谢您的回复。这是一个很好的解决方案,但在我的情况下,许多表都作为外键表“A”,更改为默认 id 将是一个非常大的努力。此外,很多代码使用像'A.objects.get(pk = "something")'这样的查询并改变主键的类型需要大量的工作。出于这个原因,我正在寻找一种不会更改密钥类型的解决方案。基地有很多年了。
好的。在那种情况下,我认为这不能在 django 中解决。 Django 要求每个实例有一个唯一的主键。即使您可以使用复合主键,我也不确定当 pk 中的一个字段是可为空的外键时是否是个好主意。
你能用ManyToMany
关系代替外键吗?无论如何,听起来这就是您在这种情况下所需要的。
我想过,但是模型“A”有额外的字段,这些字段也可能因外键“B”而异。至于这个案子,我必须确定。谢谢:-)
【参考方案1】:
您想使用复合键。 Django 不支持这个See here。有一些支持,但你不能建立关系,所以就实际使用而言,它非常有限。
目前 Django 模型仅支持该集合中的单个列, 否认许多表的自然主键是 多列。 Django 目前不能使用这些模式;他们 必须改为引入冗余的单列键(“代理” 键),强制应用程序进行任意和其他不必要的操作 选择在任何给定实例中为表使用哪个键。
【讨论】:
【参考方案2】:Django 不支持复合键。但是你可以使用unique-together
unique_together = ("name", "related_name")
【讨论】:
当我使用 unique_together 时,假设模型看起来如问题中所示。继元类模型A unique_together = ("name", "related_name") 之后,我可以有两行name = "Kriss" 不同的字段相关名称吗?我的意思是name字段primary_key参数设置为true。 >>> s = B.objects.create(name="JAN") >>> s.save() >>> d = A.objects.create(name="Stasze") >>> d.save() >>> k = A.objects.create(name="Stasze", related_name=s) return Database.Cursor.execute(self, query, params) django.db.utils.IntegrityError:唯一约束失败:test_comp_a.name 不是复合PK,记住这一点。您在A
类中使用name
属性作为PK 并创建一个重复的对象。如果您将在许多 A
对象中使用相同的 name
,请不要将其用作 PK,使用 autoincrement
作为默认值,unique_together
会解决问题。
感谢您的回复。就我而言,这并不适用,因为由于对模型 A 的大量依赖,对主键的更改并不那么容易。多亏了你,我遇到了一个新的可能性 django,将来肯定会使用它。在这种情况下,这不是我的解决方案。谢谢:-)以上是关于如何在 Django 中创建一个包含两个字段的主键?的主要内容,如果未能解决你的问题,请参考以下文章
在 IBM netezza sql server 中创建唯一的主键?