Django 中的三元模型关联

Ternary model association in Django

我建模了一个 UML class 这样的图表

我想将这个关联翻译成 Django。我有以下内容:

class Crypto(models.Model):
    cryptoName = models.CharField(max_length=64, primary_key=True)

class Worker(models.Model):
    name = models.CharField(max_length=64)
    lastname = models.CharField(max_length=64)
    email = models.EmailField(max_length=128, primary_key=True)
    tlf = models.CharField(max_length=20)

    cryptos = models.ManyToManyField(Crypto)

class Operation(models.Model):
    refNum = models.IntegerField()
    datetime = models.DateTimeField()
    amount = models.FloatField()
    amountCrypto = models.FloatField()

我一直在试图代表三元协会。 Django 具有 ManyToManyFieldthrough 属性,但是,如您所见,该关联在任何方面都不是 m2m,而主要是一对多。那么用 Django 模型表示这种三元关联的最佳方式是什么?


编辑:数据库中将注册加密货币,工作人员可以做的是启用他们想要使用的数量(或禁用,如果是这种情况)。

如果你想要一个工人有很多加密货币。然后有两个用例将定义您必须使用的内容 ManyToManyFieldForeignKey.

如果所有用户的加密货币对象总是彼此不同。

For example, If the user is registering themselves and can create there own cryptocurrencies which are always different than already available currencies.

您必须在 Crypto 模型中添加 ForeignKey,而不是在 Worker 模型中使用 ManyToManyField

class Crypto(models.Model):
    cryptoName = models.CharField(max_length=64, primary_key=True)
    worker = models.ForeignKey(Worker, related_name='cryptos')

    def __str__(self):
       return self.cryptoName

从 Worker 模型中移除加密 ManyToManyField 关系

这样,您可以拥有许多与工作人员相关的密码,并且您可以使用字段中提到的 related_name 访问工作人员的密码

worker = Worker.objects.first()
worker.cryptos
# output: <QuerySet [<Crypto: IOT>, <Crypto: BTC>, ...]>

如果用户在注册时可以从已经可用的加密货币中进行选择

That means multiple users are linking with the same object of crypto and a user can choose as many currencies.

您必须像现在一样使用ManyToManyField

并且您可以使用

简单地访问工作人员的那些货币对象
worker.cryptos
# output: <QuerySet [<Crypto: IOT>, <Crypto: BTC>, ...]>

要将加密货币链接到工作人员,您可以使用 .add()

crypto = Crypto.objects.get(cryptoName='BTC')
worker.cryptos.add(crypto)  

更新

当你创建 ManyToManyField 关系时,然后在幕后创建一个 table 来保留两个模型的引用,但是如果你想创建自己的中间table 你必须在定义 ManyToManyField

时使用 through 关键字
class Worker(models.Model):
    ...
    # rest of the fields 
    cryptos = models.ManyToManyField(Crypto, through='Operation', related_name='workers')

并将两个模型的外键手动添加到Operation模型。

class Operation(models.Model):
    ...
    # rest of fields
    worker = models.ForeignKey(Worker, related_name='operation')
    crypto = models.ForeignKey(Crypto, related_name='operation')

Check out the official docs for more info on how to use it.