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

时间:2011-04-27 00:07:45

标签: django django-admin many-to-many

我的模型包含多对多关系。 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")

我希望我的管理界面能够在Measurement管理员中内联DataSet字段,就像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.

如何在Measurement admin?

中公开DataSet的可修改字段

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

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

2 个答案:

答案 0 :(得分:5)

简短的回答:你不能。

答案很长:你不能没有大幅编辑django的ModelAdmin。它使用的InlineFormset工厂非常有限,目前无法处理ManyToManyInlines。使用ForeignKeys

支持InlineModelAdmin对象仅

对不起。

答案 1 :(得分:-1)

嗯,不确定是否真正了解您正在处理的项目,但如果您想在数据集中使用Measurement inlines,则可能需要将关系放在数据集模型中:

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对我来说很奇怪。但也许我完全错过了这一点?