Django 如何处理多对多关系?
How are many-to-many relationship handled in Django?
我有一件可以包含多种颜色的衬衫,以及可以包含多件衬衫的多种颜色。通常我会这样表达:
在 django 中我有多对多 (https://docs.djangoproject.com/en/3.1/topics/db/examples/many_to_many/)
示例:
publications = models.ManyToManyField(Publication)
--
我可以创建由 2 列(无“ID”主键)组成的 table“Item_colors”并使用复合键根据我的图表设计模型吗:
class Item_colors(models.Model):
class Meta:
unique_together = (('cloth_item_id', 'color_id'),)
cloth_item_id = models.ForeignKey(Cloth_item, on_delete=models.CASCADE)
color_id = models.ForeignKey(Color, on_delete=models.CASCADE)
如何在数据库上下文中处理多对多关系,它是否会产生更好的性能?
编辑:https://code.djangoproject.com/wiki/MultipleColumnPrimaryKeys 不避免主键以支持复合键保存列 :( 至少现在..
How is the many-to-many relation handled in a DB context, and does it yield better performance?
中间有一个交叉点 table,所以有一个 item_colors
table。但是 table 包含一个主键,就像 Django 中的每个模型一样。
如果不指定through=…
parameter [Django-doc] to define the model for the junction table yourself, Django will automatically create such model. This model then has two ForeignKey
s to the two models it connects as discussed in the database representation section of the documentation:
Behind the scenes, Django creates an intermediary join table to represent the many-to-many relationship. By default, this table name is generated using the name of the many-to-many field and the name of the table for the model that contains it. Since some databases don’t support table names above a certain length, these table names will be automatically truncated and a uniqueness hash will be used, e.g. author_books_9cdf
. You can manually provide the name of the join table using the db_table
option.
但是 table 因此有一个主键。如果同一个对象在关系中第二次出现,这可能会有用。
您可以访问 Article
-Publication
示例中的直通模型,例如:
Article.publications<b>.through</b>
因此您可以自己定义直通模型,例如:
class Color(models.Model):
color = models.CharField(max_length=128)
class ClothItem(models.Model):
item_name = models.CharField(max_length=128)
colors = models.ManyToManyField(
Color,
related_name='cloth_items'
through='ClothItemColors'
)
class ClothItemColors(models.Model):
cloth_item = models.ForeignKey(ClothItem, on_delete=models.CASCADE)
color = models.ForeignKey(Color, on_delete=models.CASCADE)
class Meta:
db_table = 'item_colors'
constraints = [
models.UniqueConstraint(
fields=('cloth_item', 'color'),
name='unique_cloth_color'
)
]
通常使用显式直通模型来存储额外信息,例如 quantity
:
class ClothItemColors(models.Model):
cloth_item = models.ForeignKey(ClothItem, on_delete=models.CASCADE)
color = models.ForeignKey(Color, on_delete=models.CASCADE)
<b>quantity</b> = models.IntegerField(default=0)
# …
我有一件可以包含多种颜色的衬衫,以及可以包含多件衬衫的多种颜色。通常我会这样表达:
在 django 中我有多对多 (https://docs.djangoproject.com/en/3.1/topics/db/examples/many_to_many/) 示例:
publications = models.ManyToManyField(Publication)
-- 我可以创建由 2 列(无“ID”主键)组成的 table“Item_colors”并使用复合键根据我的图表设计模型吗:
class Item_colors(models.Model):
class Meta:
unique_together = (('cloth_item_id', 'color_id'),)
cloth_item_id = models.ForeignKey(Cloth_item, on_delete=models.CASCADE)
color_id = models.ForeignKey(Color, on_delete=models.CASCADE)
如何在数据库上下文中处理多对多关系,它是否会产生更好的性能?
编辑:https://code.djangoproject.com/wiki/MultipleColumnPrimaryKeys 不避免主键以支持复合键保存列 :( 至少现在..
How is the many-to-many relation handled in a DB context, and does it yield better performance?
中间有一个交叉点 table,所以有一个 item_colors
table。但是 table 包含一个主键,就像 Django 中的每个模型一样。
如果不指定through=…
parameter [Django-doc] to define the model for the junction table yourself, Django will automatically create such model. This model then has two ForeignKey
s to the two models it connects as discussed in the database representation section of the documentation:
Behind the scenes, Django creates an intermediary join table to represent the many-to-many relationship. By default, this table name is generated using the name of the many-to-many field and the name of the table for the model that contains it. Since some databases don’t support table names above a certain length, these table names will be automatically truncated and a uniqueness hash will be used, e.g.
author_books_9cdf
. You can manually provide the name of the join table using thedb_table
option.
但是 table 因此有一个主键。如果同一个对象在关系中第二次出现,这可能会有用。
您可以访问 Article
-Publication
示例中的直通模型,例如:
Article.publications<b>.through</b>
因此您可以自己定义直通模型,例如:
class Color(models.Model):
color = models.CharField(max_length=128)
class ClothItem(models.Model):
item_name = models.CharField(max_length=128)
colors = models.ManyToManyField(
Color,
related_name='cloth_items'
through='ClothItemColors'
)
class ClothItemColors(models.Model):
cloth_item = models.ForeignKey(ClothItem, on_delete=models.CASCADE)
color = models.ForeignKey(Color, on_delete=models.CASCADE)
class Meta:
db_table = 'item_colors'
constraints = [
models.UniqueConstraint(
fields=('cloth_item', 'color'),
name='unique_cloth_color'
)
]
通常使用显式直通模型来存储额外信息,例如 quantity
:
class ClothItemColors(models.Model):
cloth_item = models.ForeignKey(ClothItem, on_delete=models.CASCADE)
color = models.ForeignKey(Color, on_delete=models.CASCADE)
<b>quantity</b> = models.IntegerField(default=0)
# …