Python FastAPI Tutorial (Part 6): Completing CRUD - Update and Delete (PUT, PATCH, DELETE)
Based on Corey Schafer's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.
PUT updates posts as full replacements using required fields (title, content, user_id), while PATCH applies only provided fields using optional schemas.
Briefing
CRUD in FastAPI is completed for both posts and users by adding full update (PUT), partial update (PATCH), and deletion (DELETE), with careful request validation and REST-appropriate status codes. The key operational split is that PUT replaces an entire resource using a schema where all fields are required, while PATCH applies only the fields a client actually sends using optional fields plus logic that excludes “unset” values—preventing accidental overwrites (like wiping post content when only a title changes). For posts, the update flow also includes a 404 guard when the target post doesn’t exist, plus a check that a new user ID (if provided in PUT) refers to an existing user, avoiding database constraint errors and returning cleaner API responses.
Testing through the interactive docs confirms the behavior: PUT requires sending title, content, and user ID, and successfully changes ownership when the provided user exists. PATCH, by contrast, accepts only the changed fields (for example, updating just the title) and leaves other attributes untouched. Deletion follows standard REST conventions: DELETE returns 204 No Content on success, and subsequent GET requests for the deleted resource return 404 Not Found.
Users receive the same completion treatment, with a PATCH endpoint for partial profile updates. A new user update schema makes username, email, and image file optional (defaulting to none), while preserving validation rules when values are provided (e.g., email must be a valid email format, and image file name length is constrained). Update logic includes uniqueness checks: if a client tries to change a username or email to one already in use, the API returns 400 Bad Request rather than allowing a database error. After validation, only the provided fields are applied, then the updated user is committed, refreshed, and returned.
The most consequential data-model change is cascade deletion. When a user is deleted, SQLAlchemy is configured to delete all related posts automatically via cascade settings (including orphan cleanup). This mirrors common real-world “delete account” behavior where removing an account permanently removes associated content. After implementing the user DELETE endpoint (also returning 204), deleting a user is verified to remove their posts as well—confirmed by GET requests showing only remaining posts.
Finally, the tutorial demonstrates profile picture updates without adding file-upload capability yet. By adding an optional image file field to the user update schema and storing only the filename in the database, the application can compute the full image path dynamically in the models. Manually placing an image file into the media directory and then PATCHing the user’s image file updates the displayed profile picture on the homepage, while future work will add actual upload functionality.
Across both resources, the API uses consistent HTTP status codes (200, 201, 204, 400, 404, 422) and relies on Pydantic validation for request correctness, resulting in predictable behavior for client applications.
Cornell Notes
The API adds complete CRUD support for both posts and users in FastAPI. Posts get PUT for full replacement and PATCH for partial updates; the PATCH implementation uses optional fields plus “exclude unset” logic so missing fields don’t overwrite existing data. Both post and user DELETE endpoints return 204 No Content and raise 404 Not Found when the target resource doesn’t exist. User updates validate uniqueness for username and email and allow changing a profile picture filename, with the full image path computed from model properties. Cascade deletion is enabled so deleting a user automatically deletes all their posts, matching typical account-deletion behavior.
Why does PATCH need special handling to avoid wiping fields, and how is that achieved here?
What’s the practical difference between PUT and PATCH for posts in this implementation?
How does the API prevent confusing database errors during post updates?
What uniqueness rules are enforced when updating users, and what happens when they’re violated?
How does cascade deletion work here, and what outcome does it guarantee?
How can profile pictures be updated without file uploads in this setup?
Review Questions
- When implementing PATCH, what does exclude_unset=True prevent, and what bug would occur without it?
- In what situations should a 404 Not Found be raised during update or delete operations for posts and users?
- How does cascade deletion change the expected results of deleting a user, and how would you verify it with GET requests?
Key Points
- 1
PUT updates posts as full replacements using required fields (title, content, user_id), while PATCH applies only provided fields using optional schemas.
- 2
PATCH correctness depends on exclude_unset=True so omitted fields don’t get overwritten with default None values.
- 3
Update endpoints include existence checks for the target resource and, for post ownership changes, validation that the referenced user exists.
- 4
DELETE endpoints return 204 No Content on success and 404 Not Found when the resource doesn’t exist.
- 5
User PATCH enforces uniqueness for username and email, returning 400 Bad Request when a requested value is already in use.
- 6
Cascade deletion is configured so deleting a user automatically deletes all their associated posts.
- 7
Profile picture updates are supported by PATCHing an image filename and computing the full path from model properties, with uploads added later.