Search code examples
djangomany-to-manyadmininline-formset

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


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!


Solution

  • 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 :-(