Django复杂的关系

时间:2016-01-14 10:47:00

标签: python sql django django-models orm

我有以下型号:

class A(models.Model):
    title = models.CharField(max_length=30)

class B(models.Model):
    title = models.CharField(max_length=255)
    a = models.ManyToManyField(A)

我现在想要一个模型C,它具有一个具有A和B的多个唯一组合的字段,就像在ManyToMany字段中一样。我发现,为了将ForeignKey映射到两个模型,可以使用GenericForeignKey。我已经尝试过GenericForeignKey,如下所示:

class C(models.Model):
    title = models.CharField()
    property1 = models.CharField()
    a = models.ManyToManyField(A)
    b = models.ManyToManyField(B)
    a_b = GenericForeignKey(store, category)

但是,这似乎不起作用。有人能指出我正确的方向吗?我是Django和SQL的新手。

编辑:明确了组合的要求。

Edit2:当前的工作模式:

我创建了以下模型作为工作解决方案:

class A(models.Model):
    title = models.CharField(max_length=30)

class B(models.Model):
    title = models.CharField(max_length=255)
    a = models.ManyToManyField(A)

class C(models.Model):
    title = models.CharField()
    property1 = models.CharField()

class A_B_C(models.Model):
    a = models.ForeignKey(A)
    b = models.ForeignKey(B)
    c = models.ForeignKey(C)
    class Meta:
        unique_together = ('a', 'b', 'c')

正是这种模式,我避免明确地创建和维持关系。我想知道这个解决方案是否有效还是有另一种Django方法可以做什么?

3 个答案:

答案 0 :(得分:2)

使用ManyToManyField时,Django会隐式为您创建中间表。在您的示例中,您将获得包含列(id, a_id, b_id)的其他表格。但您可以明确定义它并在through模型上的字段a上设置B选项,然后为此中间模型定义unique_together

class A(models.Model):
    title = models.CharField(max_length=30)

class B(models.Model):
    title = models.CharField(max_length=255)
    a = models.ManyToManyField(A, through='C')

class C(models.Model):
    a = models.ForeignKey(A, on_delete=models.CASCADE)
    b = models.ForeignKey(B, on_delete=models.CASCADE)

    class Meta:
        unique_together = ("a", "b")

注意:如果我没记错,您无法直接在ManyToManyFiled设置unique_together。

答案 1 :(得分:0)

这不是GenericForeignKey的工作。相反,您需要定义unique_together Meta属性:

class C(models.Model):
    ...
    class Meta
        unique_together = ('a', 'b')

答案 2 :(得分:0)

供将来参考:

我创建了以下模型作为工作解决方案:

class A(models.Model):
    title = models.CharField(max_length=30)

class B(models.Model):
    title = models.CharField(max_length=255)
    a = models.ManyToManyField(A)

class C(models.Model):
    title = models.CharField()
    property1 = models.CharField()

class A_B_C(models.Model):
    a = models.ForeignKey(A)
    b = models.ForeignKey(B)
    c = models.ForeignKey(C)

    class Meta:
        unique_together = ('a', 'b', 'c')