Django admin inline change fields on new row

Viewed 518

Background

I'm customizing the admin pages for an inventory system with a lot of ManyToMany relationships and other complex data. I want to display these relationships using Inlines, but I don't like the default drop-down field that Django uses for ManyToMany relationships in an Inline so I customized the field set. My custom fields are relatively simple, an ID field that links to the related record, readonly text fields with data from the related record since the Inline can't get fields from the related record by default; that sort of thing.

Problem

The issue is that in order to use custom fields in these inlines, I've had to make them all read-only. Normally that's fine, because you can follow the link in the ID field to the actual edit page, but it's impossible to add a new record via the button on the Inline because I can't enter any of the necessary information. My IDs aren't even auto-incremented since this data needs to sync up with another Database, so the new row doesn't link to a newly created record.

Basically, what I want to do is have a different set of writable fields on newly added rows so that required fields, like the ID, can be filled.

Issues

I've tried doing this by overloading the get_fields() and get_readonly_fields() functions, but it looks like these determine the fields for the entire inline and not for individual rows. I'm also not even positive it's possible to include a writable field for ManyToMany relationships, since the Inline is actually displaying data from an intermediate model and not the related record itself.

Code

Here's an example of one of my simple Inlines to give you a better idea of what I'm talking about:

class MetaDataInline(admin.TabularInline):
    verbose_name = 'meta data'
    verbose_name_plural = 'meta data'
    model = Product.meta_data.through
    fields = ('key', 'value')
    readonly_fields = ('key', 'value')
    extra = 0

    def key(self, obj): return obj.metadata.key
    def value(self, obj): return obj.metadata.value

And a screenshot of the Inline with a newly added row:

Sorry, I can't embed yet

As you can see, I can't add new meta data to the parent record because the new row comes up blank and unusable.

Conclusion

As I see it, this is actually two problems:

  1. How can I make an Inline render different fields for a newly added row?

  2. How can I edit related data in an Inline for a ManyToMany relationship?

Any help I can get towards answering these 2 questions, or suggestions for an alternative approach would be greatly appreciated. I know that displaying the relationship as a horizontal filter instead of an Inline would give me the functionality I want, but I dislike the way it displays my data so I want to make it work like this if possible.

0 Answers
Related