• Stars
    star
    117
  • Rank 301,828 (Top 6 %)
  • Language
    Python
  • License
    MIT License
  • Created over 6 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An example of how to use Django inline formsets, each of which contains its own inline formset

Django nested inline formsets example

This Django project is purely to demonstrate an example of how to create a form that contains inline formsets that each contains its own inline formset.

It runs in Django 4.0 using Python 3.9.

I'm indebted to this blogpost by Ravi Kumar Gadila for helping me figure this out.

The situation

We have a model describing Publishers. Each Publisher can have a number of Books. Each Book can have a number of BookImages (e.g. its cover, back cover, illustrations, etc):

Publisher #1
  |-Book
  |   |-BookImage
  |   |-BookImage
  |
  |-Book
      |-BookImage

Publisher #2
  |-Book
  |
  |-Book

See these in models.py.

Using an inline formset we could display a single form that would let the user edit all of the Books belonging to a single Publisher.

Using another inline formset we could display another form that would let the user edit all of the BookImages belonging to a single Book.

It becomes trickier if we want to combine these two forms into one: displaying all of the Books for a Publisher, and for each Book, all of its BookImages.

Solution

You can see in forms.py how we construct an inline formset, BookImageFormset for editing the BookImages belonging to a single Book.

And then we create a custom BaseBooksWithImagesFormset that has a custom nested property. This contains our BookImageFormset. We add custom methods for is_valid() and save() to ensure the data in these nested formsets are validated and saved.

Finally we create our PublisherBooksWithImagesFormset which is for editing all the Books belonging to a Publisher... and we pass it this argument: formset=BaseBooksWithImagesFormset so it knows how to handle each of the Books' BookImages.

See views.py for how we use this in a class-based view to create the page. This expects the id of a Publisher. And see the books/publisher_books_update.html template for how the outer form, and its Book formsets, and their nested BookImage formsets, are rendered.

Here's an image showing how that page looks:

Set-up

If you want to get this project running to see how it works...

  1. Download or clone the repository.

  2. Install Django and Pillow (required for the ImageField). For example, using pip with the requirements.txt file:

    pip install -r requirements.txt
    

    Or using pipenv with the Pipfiles:

    pipenv install
    

    (If using pipenv, enter the virtual environment before running the following commands, by doing pipenv shell)

  3. Run the migrations:

    ./manage.py migrate
    
  4. Create a superuser if you want to use the Django Admin:

    ./manage.py createsuperuser
    
  5. Run the development server:

    ./manage.py runserver
    
  6. View the site at http://127.0.0.1:8000/ and add at least one Publisher.

  7. You can then click the link to add some Books to your Publisher. You'll then be on a page like http://127.0.0.1:8000/publishers/1/books/edit/ which is the form with its inline formsets.

Thanks

More Repositories

1

python-halftone

A python module that uses PIL/Pillow to give images a halftone effect
Python
84
star
2

django-ditto

A collection of Django apps for copying things from third-party sites and services.
Python
79
star
3

mailman-archive-scraper

Python script that scrapes public and private Mailman archive pages and republishes them to local files, and generates an RSS feed of recent emails.
Python
53
star
4

django-spectator

A Django app to track book/magazine reading and event going.
Python
43
star
5

twelescreen

A fullscreen, one-Tweet-at-a-time Twitter display. Runs on Node.js.
JavaScript
40
star
6

simplenote-to-obsidian

A python script to convert an export of Simplenote notes for use in Obsidian
Python
32
star
7

daily-paper

For viewing a daily issue of the Guardian and Observer newspapers. `main` branch should be stable, current work is in `dev` branch.
JavaScript
26
star
8

foursquare-feeds

A python script for generating an iCal feed from your Foursquare checkins
Python
25
star
9

flickr-download-favorites

Python script to download faved photos and 'photos of you' from Flickr
Python
23
star
10

django-docker-example

My example Django setup using Docker for local development.
Python
22
star
11

django-hines

Code for my personal website
HTML
15
star
12

pepysdiary

Code for PepysDiary.com
Python
14
star
13

ansible-multi-django

Ansible playbook for setting up servers with multiple Django sites
Shell
11
star
14

ffffound-export

Python script for exporting an account's images from Ffffound.com
Python
7
star
15

s3-backup

A python 3 script for backing up S3 buckets and folders to a local filesystem
Python
5
star
16

vagrant-heroku-cedar-14-python

A Vagrant box for python/Django development, mimicking a Heroku cedar-14 dyno.
Shell
5
star
17

vim-files

Phil Gyford's vim set-up
Vim Script
3
star
18

django-url-namespace-example

A Django project to demonstrate how to nest URL namespaces
Python
2
star
19

col-scraper

Scripts for scraping data about City of London councillors and saving to JSON/SQLite
Python
2
star
20

uk-parliament-demographics

Chart comparing the UK parliament's demographics with the UK population
JavaScript
1
star
21

django-archivr

Python
1
star
22

django-commentstest

Testing custom comments and moderation
Python
1
star
23

vagrant-heroku-cedar-16-python

A Vagrant box for python/Django development, mimicking a Heroku cedar-16 dyno.
Shell
1
star
24

django-ditto-demo

A simple site to demonstrate django-ditto
Python
1
star
25

pinboard-to-mt

Make a new Movable Type weblog Entry from a day's worth of your Pinboard links
Python
1
star
26

find-addresses-in-emlx

Find which 'From' addresses and domains are used most in a folder of .emlx files
Python
1
star