我在 models.py 中有以下表格:
class Part(models.Model):
partno = models.CharField(max_length=50, unique=True)
partdesc = models.CharField(max_length=50, default=None, blank=True, null=True)
class Price(models.Model):
part = models.ForeignKey(Part, on_delete=models.CASCADE, null=True)
supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE)
qty = models.IntegerField(default=1)
price = models.DecimalField(max_digits=9, decimal_places=2)
currency = models.ForeignKey(Currency, on_delete=models.CASCADE)
datestart = models.DateTimeField(auto_now_add=True, blank=False, null=False)
class Meta:
unique_together = (('supplier', 'part'),)
这可以正常工作。问题是我有很多零件号是它们的替代品。例如,部件 1001-01、1001-02、1001-03 都是相同的部件。尽管如此,我的零件表中仍然有所有这些。
我需要在另一个表中匹配它们,所以我不需要单独输入每个的价格。必须有一个唯一的键来代表所有这三项。
问题:如何设置“零件编号匹配表”并在我的价格表中拥有该表的外键?
(休息可以选择阅读到目前为止我的观点/问题,但可能会有所帮助)
1:我尝试像这样设置表格:
class PartMatch(models.Model):
id = models.IntegerField(primary_key=True, unique=False, null=False, db_index=True)
part = models.ForeignKey(Part, unique=False, on_delete=models.CASCADE)
我在迁移时没有收到错误,但当我尝试使用相同的 id 进行 PK 时,它不允许我这样做。
2:我不理会 pk 并尝试设置另一个字段来匹配零件:
class PartMatch(models.Model):
part = models.ForeignKey(Part, on_delete=models.CASCADE)
partmatchid = models.IntegerField(null=True, unique=False, db_index=True)
我在迁移时没有收到任何错误,但当我尝试使用 partmatchid
作为 Price
表中的外键时,如下所示:
partmatch = models.ForeignKey(PartMatch, to_field="partmatchid",
db_column="partmatchid",
on_delete=models.CASCADE)
迁移时出现错误,提示外键必须是唯一的
。
在这种情况下我没有解决方案。我想知道你们如何处理这个问题?
最佳答案
您的Part
模型可以有一个外键 PartMatch
,而不是相反。
您的型号可以是Part *<-->1 PartMatch
和PartMatch 1<-->1 Price
例如:
class Price(models.Model):
price = models.DecimalField(max_digits=9, decimal_places=2)
class PartMatch(models.Model):
price = models.OneToOneField(Price, primary_key=True)
class Part(models.Model):
partno = models.CharField(max_length=50, unique=True)
partMatch = models.ForeignKey(PartMatch)
如果您想以一定的价格获得所有零件,some_price.partmatch.part_set.all()
会完成这项工作。
关于mysql - 如何创建一个具有非唯一ID的表并将其作为另一个表中的外键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46264938/