import uuid
from django.db import models
class Cart(models.Model):
OPEN = "open"
PROCESSING = "processing"
PAID = "paid"
STATUS_CHOICES = [(OPEN, "Open"), (PROCESSING, "Processing"), (PAID, "Paid")]
user = models.ForeignKey("auth.User", on_delete=models.CASCADE)
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default=OPEN)
idempotency_key = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
total_cents = models.PositiveIntegerField(default=0)
def is_open(self):
return self.status == self.OPEN
class Order(models.Model):
cart = models.OneToOneField(Cart, on_delete=models.PROTECT, related_name="order")
charge_id = models.CharField(max_length=64)
amount_cents = models.PositiveIntegerField()
created_at = models.DateTimeField(auto_now_add=True)
from django.db import transaction, IntegrityError
from .models import Cart, Order
from .payments import charge_card
class AlreadyProcessed(Exception):
def __init__(self, order):
self.order = order
@transaction.atomic
def place_order(cart_id, payment_token):
# Acquire a row lock; a second concurrent request blocks here until we commit.
cart = Cart.objects.select_for_update().get(pk=cart_id)
# Re-check state *inside* the lock, not before it.
if not cart.is_open():
raise AlreadyProcessed(cart.order)
cart.status = Cart.PROCESSING
cart.save(update_fields=["status"])
charge = charge_card(payment_token, cart.total_cents, cart.idempotency_key)
try:
order = Order.objects.create(
cart=cart,
charge_id=charge["id"],
amount_cents=cart.total_cents,
)
except IntegrityError:
# Unique cart constraint lost the race; treat as already done.
raise AlreadyProcessed(Order.objects.get(cart=cart))
cart.status = Cart.PAID
cart.save(update_fields=["status"])
return order
from django.http import JsonResponse, Http404
from django.views import View
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from .models import Cart
from .checkout import place_order, AlreadyProcessed
@method_decorator(login_required, name="dispatch")
class CheckoutView(View):
def post(self, request, cart_id):
token = request.POST.get("payment_token")
if not token:
return JsonResponse({"error": "missing payment_token"}, status=400)
try:
order = place_order(cart_id, token)
except Cart.DoesNotExist:
raise Http404("cart not found")
except AlreadyProcessed as exc:
return JsonResponse(
{"order_id": exc.order.id, "status": "already_processed"},
status=200,
)
return JsonResponse(
{"order_id": order.id, "status": "created"},
status=201,
)
This snippet shows how a checkout endpoint in Django is protected against double-submission, the classic race where an impatient user double-clicks or a mobile client retries, and two requests try to charge and fulfill the same cart at once. The core technique is a database row lock acquired with select_for_update() inside transaction.atomic(), so that concurrent requests serialize on the cart row rather than racing through the same code path.
In models.py, the Cart carries a status field and a unique idempotency_key, while Order has a one-to-one link back to the cart. The uniqueness of cart on Order is a second line of defense: even if application logic fails, the database will reject a second order for the same cart. The Cart.is_open() helper centralizes the state check the view relies on.
In checkout.py, place_order wraps everything in transaction.atomic() and immediately calls Cart.objects.select_for_update().get(...). This issues a SELECT ... FOR UPDATE, taking a write lock on that cart row; a second concurrent transaction blocks on that same row until the first commits. Once the lock is held, the code re-reads status inside the critical section — a check performed before the lock would be worthless, since the value could change between the read and the write. If the cart is no longer open, AlreadyProcessed is raised and the existing order is returned, making the operation effectively idempotent. Only after charging does it flip the status and create the Order; the IntegrityError guard turns a lost race on the unique constraint into the same idempotent result.
In views.py, CheckoutView.post translates these outcomes into HTTP: a fresh order yields 201, an already-processed cart yields 200 with the same order id, and a missing cart yields 404. Because the whole body runs in one atomic block, a failure anywhere rolls back the status change and the order together, never leaving a cart half-fulfilled.
The main trade-off is that select_for_update requires a real transaction and a backend that supports row locks such as PostgreSQL; it does not work with sqlite. Locks are held until commit, so the critical section should stay short and avoid slow external calls where possible.
Related snips
class Product(models.Model):
name = models.CharField(max_length=200)
slug = models.SlugField(blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
cost = models.DecimalField(max_digits=10, decimal_places=2)
margin = models.DecimalField(max_digits=5, decimal_places=2, blank=True)
Django model signals vs overriding save
package dbutil
import (
"context"
"github.com/jackc/pgconn"
Retry Postgres serialization failures with bounded attempts
require "csv"
class PeopleCsvStream
include Enumerable
HEADERS = %w[id full_name email signed_up_at plan].freeze
Resilient CSV Export as a Streamed Response
class SignupForm
include ActiveModel::Model
include ActiveModel::Attributes
attribute :account_name, :string
attribute :email, :string
Shallow Controller, Deep Params: Form Object Pattern
use crossbeam::channel::unbounded;
use std::thread;
fn main() {
let (tx, rx) = unbounded();
Crossbeam for advanced concurrent data structures
// Creating a Promise
const myPromise = new Promise((resolve, reject) => {
const success = true;
setTimeout(() => {
if (success) {
Promises and async/await patterns for asynchronous JavaScript
Share this code
Here's the card — post it anywhere.