如何在多对多关系中使用带有可编辑字段的 TabularInline?

Posted

技术标签:

【中文标题】如何在多对多关系中使用带有可编辑字段的 TabularInline?【英文标题】:How do I use a TabularInline with editable fields on a ManyToMany relationship? 【发布时间】:2011-08-13 11:09:34 【问题描述】:

我的模型包含多对多关系。 Measurements 可以是任意数量的DataSets 的一部分。

# models.py
from django.db import models

class DataSet(models.Model):
    purpose = models.TextField()

class Measurement(models.Model):
    value = models.IntegerField()
    sets = models.ManyToManyField(DataSet, null=True, blank=True,
                         verbose_name="datasets this measurement appears in")

我希望我的管理界面在DataSet 管理中内联Measurement 字段,就像TabularInline 如何与ForeignKey 字段一起使用一样。这是我目前所拥有的:

# admin.py
from django.contrib import admin
from myapp.models import Measurement, DataSet

class MeasurementInline(admin.TabularInline):
    model = Measurement.sets.through

class DataSetAdmin(admin.ModelAdmin):
    inlines = [MeasurementInline]

admin.site.register(DataSet, DataSetAdmin)

不幸的是,我得到的只是下拉框,旁边带有“+”按钮,可以打开测量管理。我希望在内联中公开实际的测量字段value。我尝试将 value 添加到 MeasurementInline 的字段列表中:

# admin.py    
class MeasurementInline(admin.TabularInline):
    model = Measurement.sets.through
    fields = ['value']

但这给了我一个错误:'MeasurementInline.fields' refers to field 'value' that is missing from the form.

如何在DataSet 管理员中公开Measurement 的可编辑字段?

注意事项: 这是一个简化的案例;我的真实案例在其Measurement 模型中有很多字段。如果使用管理界面的人必须打开一个新窗口来输入数据,那将是非常乏味的,尤其是因为他们还需要在字段之间进行一些复制和粘贴。

即使在我的真实模型中,我希望用户内联编辑的数据也没有描述DataSetMeasurement 之间的关系——只有Measurement 本身。我相信这使得中间模型不适合我的目的。

【问题讨论】:

【参考方案1】:

简短的回答:你不能。

长答案:您必须对 django 的 ModelAdmin 进行大量编辑。它使用的 InlineFormset 工厂非常有限,目前无法处理 ManyToManyInlines。 InlineModelAdmin 对象支持 ForeignKeys。

对不起。

【讨论】:

【参考方案2】:

好吧,不确定是否真正了解您正在从事的项目,但如果您想在 Dataset 中测量 inlines,您可能希望将关系放入 Dataset 模型中:

class DataSet(models.Model):
    purpose = models.TextField()
    measurements = models.ManyToManyField(DataSet, null=True, blank=True)

class Measurement(models.Model):
    value = models.IntegerField()

在你的 admin.py 中,简单地说:

class MeasurementInline(admin.TabularInline):
    model = Measurement

class DataSetAdmin(admin.ModelAdmin):
    inlines = [MeasurementInline]

admin.site.register(DataSet, DataSetAdmin)

使用model = Measurement.sets.through 对我来说看起来很奇怪。但也许我完全没有抓住重点?

【讨论】:

这行不通,因为没有从测量返回数据集的外键。

以上是关于如何在多对多关系中使用带有可编辑字段的 TabularInline?的主要内容,如果未能解决你的问题,请参考以下文章

如何在多对多关系中更新日期

Android Room - 带有附加字段的多对多关系

如何在多对多关系上使用休眠和 JPA 删除孤立实体?

学说2:在多对多关系中引用连接表

带有额外列的多对多自引用原则

如何在多对多关系 Laravel 中检索所有相关模型?