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
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Inline formsets let one view manage a parent record and its related children in a single form submission.
- 2Wrapping multi-step saves in transaction.atomic keeps parent, children, and derived totals consistent.
- 3commit=False gives you a chance to attach the parent relation before persisting child rows.
Related explainers
python
from fastapi import FastAPI, WebSocket, WebSocketDisconnect app = FastAPI()
Building a WebSocket chat with FastAPI
websockets
broadcast
connection-management
Intermediate
9 steps
php
<?php namespace App\Services\Checkout;
Validating coupons with Laravel's Pipeline
pipeline
chain of responsibility
transactions
Intermediate
7 steps
python
import time import uuid from django.utils.deprecation import MiddlewareMixin
Attaching per-request context in Django
middleware
request lifecycle
multi-tenancy
Intermediate
7 steps
python
import random from typing import Iterator, List
How reservoir sampling picks k items
reservoir-sampling
streaming
randomness
Intermediate
5 steps
python
import secrets from django.contrib.auth import authenticate, login from django.core.cache import cache
Two-factor login with OTP in Django
two-factor-auth
one-time-passwords
caching
Intermediate
9 steps
python
import re from functools import total_ordering from typing import Optional
Parsing and comparing semantic versions
regex
operator-overloading
sorting
Intermediate
7 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/editing-an-order-with-inline-formsets-in-django-explained-python-d33e/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.