如何在 Django 中向多对多关系中添加字段?
Posted
技术标签:
【中文标题】如何在 Django 中向多对多关系中添加字段?【英文标题】:How can I add a field to a many-to-many relationship in Django? 【发布时间】:2021-04-02 11:16:01 【问题描述】:这是一个关于如何在Django中为多对多关系添加字段的问题。
我有一个模型 LandingPage 和一个模型 Product。 (下面的代码)。在我的项目中,LandingPages 上可以列出许多产品,并且这些相同的产品可以出现在多个不同的 LandingPages 上。
产品通过 ManyToManyField 连接到 LandingPage。
我的目标:
我试图弄清楚如何添加一个字段,以便我可以在其关联的 LandingPages 上设置产品的顺序(1 到 10)。提醒一下,Product 实例可以出现在多个 LandingPages 上,因此每个实例都需要有不同的 order 属性。
理想情况下,我想通过内置的 Django 管理员公开此功能。现在它显示了关系表,但不显示 order 字段,因为它还不存在。 (下面的屏幕截图/模型)。
我的代码:
models.py
class LandingPage(models.Model):
"""Stores a single LandingPage and metadata.
"""
name = models.CharField(max_length=200, help_text="The name is only used internally. It is not visible to the public.")
slug = models.SlugField(default="", editable=False, max_length=150, null=False, verbose_name="Slug", help_text="This is not editable.")
# Additional fields that I do not believe are relevant
class Product(models.Model):
"""Stores a single Product and metadata.
"""
name = models.CharField(max_length=200, help_text="Used internally. Not visible to the public.")
active = models.BooleanField(default=False, verbose_name="Product is Live on Landing Pages", help_text="Determines whether the product should be visible on the assocaited landing page or not.")
landing_page = models.ManyToManyField(
LandingPage,
verbose_name="Landing Page",
help_text="The landing page or pages that this product is assocaited with.",
)
# Additional fields that I do not believe are relevant
admin.py
# Inline configuration used by LandingPageAdmin
class ProductInline(admin.TabularInline):
"""Creates Inline table format for displaying Product data."""
model = Product.landing_page.through
extra = 0
class LandingPageAdmin(admin.ModelAdmin):
"""Specifies LandingPage data in Admin."""
readonly_fields=('slug',)
inlines = [ProductInline]
save_as = True
# Inline configuration used by Product Admin
class LandingPageInline(admin.TabularInline):
"""Creates Inline table format for displaying LandingPage data."""
model = LandingPage.product_set.through
extra = 0
class ProductAdmin(admin.ModelAdmin):
"""Specifies Product data in Admin."""
inlines = [LandingPageInline]
save_as = True
模型(为清楚起见):
当前状态
期望状态
(为了清楚起见,我在红色中添加了所需的功能。顺序整数应该是可编辑,以便可以重新排列顺序。)
我的问题
如何实现将可编辑的order 字段添加到此预先存在的关系的目标?
我应该手动将 order 字段添加到由 Django 自动创建的 product-landingpage 连接表吗?如果我这样做,有没有办法让 Django 管理员显示添加的字段?
或者我应该采取完全不同的方式吗?
提前谢谢你!
【问题讨论】:
【参考方案1】:我找到了答案。
解决方案是创建一个中间模型并使用“through”连接它。示例如下:
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __str__(self):
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
官方文档在这里:https://docs.djangoproject.com/en/3.1/topics/db/models/#intermediary-manytomany
在我的情况下,其他人可能会发现阅读此问题/答案很有用,因为它很好地解释了各种解决方案:Define an order for ManyToManyField with Django
【讨论】:
以上是关于如何在 Django 中向多对多关系中添加字段?的主要内容,如果未能解决你的问题,请参考以下文章