maazza maazza - 1 month ago 12
Python Question

django admin inline many to many custom fields

Hi I am trying to customize my inlines in django admin.

Here are my models:

class Row(models.Model):
name = models.CharField(max_length=255)

class Table(models.Model):
rows = models.ManyToManyField(Row, blank=True)
name = models.CharField(max_length=255)

def __unicode__(self):
return self.name


and my admin:

class RowInline(admin.TabularInline):
model = Table.rows.through
fields = ['name']


class TableAdmin(admin.ModelAdmin):
inlines = [
RowInline,
]
exclude = ('rows',)


However I get this error


ImproperlyConfigured at /admin/table_app/table/1/

'RowInline.fields' refers to field 'name' that is missing from the
form.


How is that possible ?

sj7 sj7
Answer Source
class RowInline(admin.TabularInline):
    model = Table.rows.through
    fields = ['name']

This presents a problem because Table.rows.through represents an intermediate model. If you would like to understand this better have a look at your database. You'll see an intermediate table which references this model. It is probably named something like apname_table_rows. This intermeditate model does not contain the field, name. It just has two foreign key fields: table and row. (And it has an id field.)

If you need the name it can be referenced as a readonly field through the rows relation.

class RowInline(admin.TabularInline):
    model = Table.rows.through
    fields = ['row_name']
    readonly_fields = ['row_name']

    def row_name(self, instance):
        return instance.row.name
    row_name.short_description = 'row name'


class TableAdmin(admin.ModelAdmin):
    inlines = [
        RowInline,
    ]
    exclude = ('rows',)