python 47 lines · 9 steps

Editing an order with inline formsets in Django

A single view edits a parent order and its child line items together, saving both atomically.

Explained by highlit
1from django.db import transaction
2from django.forms import inlineformset_factory
3from django.shortcuts import get_object_or_404, redirect, render
4 
5from .forms import OrderForm, OrderLineItemForm
6from .models import Order, OrderLineItem
7 
8LineItemFormSet = inlineformset_factory(
9 Order,
10 OrderLineItem,
11 form=OrderLineItemForm,
12 fields=["product", "quantity", "unit_price"],
13 extra=1,
14 can_delete=True,
15)
16 
17 
18def edit_order(request, pk):
19 order = get_object_or_404(Order.objects.prefetch_related("line_items"), pk=pk)
20 
21 if request.method == "POST":
22 form = OrderForm(request.POST, instance=order)
23 formset = LineItemFormSet(request.POST, instance=order)
24 
25 if form.is_valid() and formset.is_valid():
26 with transaction.atomic():
27 order = form.save()
28 line_items = formset.save(commit=False)
29 for item in line_items:
30 item.order = order
31 item.save()
32 for item in formset.deleted_objects:
33 item.delete()
34 order.recalculate_total()
35 return redirect("orders:detail", pk=order.pk)
36 else:
37 form = OrderForm(instance=order)
38 formset = LineItemFormSet(
39 instance=order,
40 initial=[{"unit_price": order.customer.default_price}],
41 )
42 
43 return render(
44 request,
45 "orders/edit.html",
46 {"form": form, "formset": formset, "order": order},
47 )
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Inline formsets let one view manage a parent record and its related children in a single form submission.
  2. 2Wrapping multi-step saves in transaction.atomic keeps parent, children, and derived totals consistent.
  3. 3commit=False gives you a chance to attach the parent relation before persisting child rows.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Editing an order with inline formsets in Django — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code