Django ManyToMany字段以及额外的字段不显示在两个关系上

时间:2016-02-26 07:29:30

标签: python django many-to-many django-orm

我有一个班级Assembly

class Assembly(models.Model):

    room = models.ForeignKey("Room", related_name="assemblies")
    name = models.CharField(max_length=200)
    number = models.IntegerField()
    position = models.CharField(max_length=200, blank=True)
    components = models.ManyToManyField("material.Component", through="m2m_Assembly_Components")
    connections = models.ManyToManyField("Assembly", through="Connection")
    category = models.ForeignKey("Category", default=0)
    notes = models.TextField(blank=True)

在自身实例之间具有ManyToMany Realtionship(connections)。 我使用中间表Connection,以便我可以为Assembly的两个实例之间的连接添加其他字段。

class Connection(models.Model):

    source = models.ForeignKey("Assembly", related_name="source_assembly", null=True)
    destination = models.ForeignKey("Assembly", related_name="destination_assembly", null=True)
    length = models.IntegerField(null=True, blank=True)

如果我有两个程序集,让我们说A和B,我通过定义一个新的Connection与A作为源,B作为目的地来连接它们,我得到B作为A的连接(A.connections.all()),但我不知道不能把A作为B的关系。

如果我不使用中间表,只需models.ManyToManyField("Assembly")我将A作为B的连接而B作为A的连接。

这里有什么问题?

2 个答案:

答案 0 :(得分:2)

我认为您需要为ManyToManyField指定through_fields参数。

当Django自动生成你的直通模型时,它知道其中的两个ForeignKey中的哪一个对应于" local"关系的结束,以及"远程"结束。但是,当您指定自定义中间模型时,这会使其更加困难。 Django可能只是将中间模型中的第一个ForeignKey指向正确的目标模型,在这两种情况下恰好都是source(虽然我不确定这是真的如果是这样的话,那可能就是一个错误。)

尝试查看使用through_fields=('source', 'destination')是否有帮助。

答案 1 :(得分:2)

关注@ koniiiik关于through_fields的答案:

  

使用中间模型的递归关系总是被定义为非对称的 - 也就是说,symmetrical=False - 因此,有“source”“target”的概念。在这种情况下,'field1'将被视为关系的“source”'field2'将被视为“target”

并且,在您的情况下,它是sourcedestination

由于您使用的是中间模型Connection,因此该关系不再对称。因此,A.connections.all()B.connections.all()会返回不同的结果。

A.connections.all() #all assemblies where A is source
B.connections.all() # all assemblies where B is source

如果您添加连接:

Connection(source=A, destination=B)

您可以使用以下方法找到B所在的所有程序集:

B.destination_assembly.all().values_list('source', flat=True) # this will include A