Django admin: Inline of a Many2Many model with 2 foreign keys

638 views Asked by At

after wracking my brain for days, I just hope someone can point me to the right approach. I have 4 Models: Page, Element, Style and Post.

Here is my simplyfied models.py/admin.py excerpt: http://pastebin.com/uSHrG0p2

In 2 sentences:

A Element references 1 Style and 1 Post (2 FKs).

A Page can reference many Elements, Elements can be referenced by many pages (M2M).

On the admin site for Page instances I included the M2M relation as 'inline'. So that I have multiple rows to select Element-instances. One row looking like: [My Post A with My Style X][V]

What I want is to replace that one dropdown with 2 dropdowns. One with all instances of Post and one with all instances of Style (creating Element instances in-place). So that one row would look similar to the Element admin site: [My Post A][V] [My Style X][V]

Sounds easy, but I'm just completely lost after reading and experimenting for 2 days with ModelForms, ModelAdmins, Formsets, ... . Can I do that without custom views/forms within the Django admin functionality?

One of my approaches was to access the Post/Style instances from a PageAdminForm like this, trying to create a form widget manually from it... but failed to do so:

p = Page.objects.get(pk=1)
f = PageAdminForm(instance=p)
f.base_fields['elements'].choices.queryset[0].post

Any advice or hint which way I need to go? Thank you for your time!

1

There are 1 answers

0
user640916 On BEST ANSWER

I got exactly what I wanted after removing the M2M field and linking Elements to a Page with a 3rd ForeignKey in Element:

class Element(models.Model):
    page = models.ForeignKey(Page)        
    post = models.ForeignKey(Post)
    style = models.ForeignKey(Style)

Actually a non-M2M link makes more sense for my application after all.

Memo to self: Rethink model relations before trying to outsmart Django :-(