Django中的三元模型关联

4

我已经建立了一个像这样的UML类图:

三元关联的UML图

我想将这个关联转换为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在ManyToManyField中使用through属性,但正如你所看到的,该关联方式并不是多对多关系,而主要是一对多关系。那么使用Django模型表示这种三元关联的最佳方法是什么?


编辑:数据库中将有加密货币注册,工人们可以启用他们想要的数量(或者禁用,如果需要的话)。

1个回答

4

如果你想要一个拥有多种加密货币的工人,那么有两种用例将定义你必须使用ManyToManyFieldForeignKey

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

例如,如果用户正在注册自己并可以创建与已有货币始终不同的自己的加密货币。

你必须在你的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>, ...]>

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

这意味着多个用户将与同一加密对象进行链接,一个用户可以选择多种货币。

由于您正在使用现有的 ManyToManyField,因此必须继续使用它。

您可以通过简单访问那些货币工人的对象来实现此目的。

worker.cryptos
# output: <QuerySet [<Crypto: IOT>, <Crypto: BTC>, ...]>

将加密货币与工人关联,可以使用.add()方法。

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

更新

当您创建ManyToManyField关系时,系统会在后台创建一张表来存储两个模型之间的引用。但如果您想要创建自己的中间表,则需要在定义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')

查看官方文档,了解如何使用它。

谢谢!我认为外键足够了,因为在这种情况下,我希望所有不同的工人都能注册尽可能多的货币。然而,我认为许多对多关系(如果我没有错的话)在Django中由ManyToManyField表示,而在一对多关系的情况下使用外键。您是否建议我修改类图,使handles Worker和Cryptocurrency之间的关联变为一对多? - oneberenjena
@oneberenjena 不是的,有两种用例,请查看我的更新答案。 - Satendra
现在我明白了。这正是我需要的,因为加密货币将可供用户在其应用程序中启用/禁用,但他们不能注册任何他们想要创建不同对象的加密货币。谢谢。然而,我仍然无法表示WorkerCryptoOperation之间的三元关联。 - oneberenjena
请查看我的答案中的更新部分,你必须需要使用 through 关键字。 - Satendra
1
@oneberenjena 这有帮助吗? - Satendra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接