Python FullStack Frontend Backend Guide
Python FullStack Frontend Backend Guide
FULL-STACK
DEVELOPMENT
Frontend • Backend • APIs • Databases • Deployment
HTML/CSS JavaScript Flask Django
■ Flask & Django Backends ■ FastAPI & REST APIs ■ SQL & NoSQL Databases
■ Authentication & Security ■ Docker & Deployment ■ 50+ Projects & Labs
■ TABLE OF CONTENTS
PART 6: DATABASES
Ch 31: SQL Fundamentals — SELECT to JOINs ······················· pg 494
Ch 32: PostgreSQL — Advanced Features ··························· pg 512
Ch 33: SQLAlchemy ORM — Deep Dive ······························· pg 528
Ch 34: MongoDB & NoSQL Databases ································ pg 544
Ch 35: Redis — Caching & Sessions ······························· pg 560
PART 1
FRONTEND FOUNDATIONS
HTML · CSS · JavaScript · Responsive Design
Chapter 1
HTML (HyperText Markup Language) is the backbone of every webpage. It defines the structure and
meaning of web content using elements (tags). HTML5, the modern standard, introduced semantic
elements that clearly describe their purpose — making pages more accessible, SEO-friendly, and
maintainable.
HTML5 BOILERPLATE
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="My awesome webpage">
<title>My First HTML Page</title>
<link rel="stylesheet" href="[Link]">
</head>
<body>
<header>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
</header>
<main>
<h1>Welcome to My Page</h1>
<p>HTML5 makes web development easier!</p>
</main>
<footer>
<p>© 2025 My Website</p>
</footer>
<script src="[Link]"></script>
</body>
</html>
Site/section header
Navigation links
Primary content
Thematic grouping
Self-contained content
Sidebar/related content
Bottom of page/section
HTML5 FORM
<label for="age">Age</label>
<input type="number" id="age" name="age" min="1" max="120">
■ NOTE
Always use <label> elements with matching for="" attributes. This improves
accessibility and lets users click the label to focus the input.
Chapter 2
CSS (Cascading Style Sheets) controls visual presentation. The "cascade" means styles from
multiple sources combine with a defined priority. Understanding the box model and specificity are the
two most important CSS concepts.
/* Border */
border: 2px solid #1565C0;
border-radius: 8px; /* rounded corners */
/* Background */
background: #fff;
background: linear-gradient(135deg, #667eea, #764ba2);
/* Shadow */
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
CSS SELECTORS
/* Combinators */
nav > a { color: red; } /* direct child */
p + p { margin-top: 0; } /* adjacent sibling */
p ~ p { color: gray; } /* general sibling */
/* Pseudo-classes */
a:hover { text-decoration: underline; }
li:nth-child(odd) { background: #f0f0f0; }
input:focus { outline: 2px solid #1565C0; }
button:disabled { opacity: 0.5; cursor: not-allowed; }
/* Pseudo-elements */
p::first-line { font-weight: bold; }
.card::before { content: "★ "; color: gold; }
/* Attribute selectors */
input[type="email"] { border-color: blue; }
a[href^="https"] { color: green; } /* starts with */
CSS VARIABLES
.btn {
background: var(--color-primary);
padding: var(--spacing-sm) var(--spacing-md);
border-radius: var(--border-radius);
box-shadow: var(--shadow);
}
/* Dark mode */
@media (prefers-color-scheme: dark) {
:root { --color-text: #e0e0e0; --bg: #1a1a2e; }
}
Chapter 3
FLEXBOX
/* Flex items */
.item {
flex: 1; /* grow and shrink equally */
flex: 0 0 200px; /* fixed 200px, no grow/shrink */
align-self: flex-start; /* override container alignment */
order: 2; /* change visual order */
}
CSS GRID
/* Spanning cells */
.featured { grid-column: span 2; grid-row: span 2; }
RESPONSIVE CSS
/* Tablet (≥768px) */
@media (min-width: 768px) {
.container { max-width: 768px; margin: 0 auto; }
.card-grid { grid-template-columns: repeat(2, 1fr); }
}
/* Desktop (≥1024px) */
@media (min-width: 1024px) {
.container { max-width: 1200px; }
.card-grid { grid-template-columns: repeat(3, 1fr); }
.sidebar { display: block; }
}
/* Dark mode */
@media (prefers-color-scheme: dark) {
body { background: #0d0d1a; color: #e0e0e0; }
}
Chapter 5
JAVASCRIPT ES6+
// ■■ Variables ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
const name = "Alice"; // immutable binding
let age = 25; // mutable, block-scoped
// var is function-scoped — avoid in modern JS
// ■■ Destructuring ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
const [a, b, ...rest] = [1, 2, 3, 4, 5];
// a=1, b=2, rest=[3,4,5]
const obj1 = { x: 1, y: 2 };
const obj2 = { ...obj1, z: 3 }; // { x:1, y:2, z:3 }
ARRAY METHODS
// find / findIndex
const first_big = [Link](n => n > 5); // 6
// every / some
const allPos = [Link](n => n > 0); // true
const hasOdd = [Link](n => n % 2 !== 0);// true
// flat / flatMap
const nested = [[1,2],[3,4]].flat(); // [1,2,3,4]
ASYNC JAVASCRIPT
// ■■ Promises ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
function fetchUser(id) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (id > 0) resolve({ id, name: "Alice" });
else reject(new Error("Invalid ID"));
}, 1000);
});
}
PART 2
REACT
Modern Frontend Development with Components
Chapter 8
React is a JavaScript library for building user interfaces using a component-based architecture.
Components are reusable, isolated pieces of UI. React uses a Virtual DOM to efficiently update only
what changed — making apps fast and performant.
App
Hero Cards
SETUP
REACT JSX
// Functional component
function Welcome({ name, age }) {
const isAdult = age >= 18;
return (
<div className="welcome-card">
<h1>Hello, {name}!</h1>
<p>Age: {age}</p>
{isAdult && <span className="badge">Adult</span>}
{/* Conditional rendering */}
{age < 18 ? <p>Minor</p> : <p>Adult</p>}
</div>
);
}
■ NOTE
Always provide a unique key prop when rendering lists. React uses keys to track
which items changed, were added, or removed. Never use array index as key if the
list can reorder.
Chapter 10
USESTATE HOOK
return (
<div>
<h2>Count: {count}</h2>
<button onClick={() => setCount(c => c + 1)}>+1</button>
<button onClick={() => setCount(c => c - 1)}>-1</button>
<button onClick={() => setCount(0)}>Reset</button>
</div>
);
}
USEEFFECT HOOK
useEffect(() => {
// Run when userId changes
let cancelled = false; // prevent stale updates
// Cleanup function
return () => { cancelled = true; };
}, [userId]); // dependency array
CUSTOM HOOKS
useEffect(() => {
fetch(url)
.then(r => [Link]())
.then(setData)
.catch(setError)
.finally(() => setLoading(false));
}, [url]);
// ■■ useLocalStorage ■■■■■■■■■■■■■■■■■■■■■■■■■■■
function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() =>
[Link]([Link](key)) ?? initialValue
);
useEffect(() => {
[Link](key, [Link](value));
}, [key, value]);
return [value, setValue];
}
// Usage
const { data: users, loading } = useFetch('/api/users');
const [theme, setTheme] = useLocalStorage('theme', 'light');
PART 3
FLASK
Python Micro Web Framework — Backend Development
Chapter 14
Flask is a lightweight WSGI micro-framework for Python. "Micro" means Flask keeps the core simple
and extensible — you add only what you need. Despite its simplicity, Flask powers production apps at
Pinterest, LinkedIn, and Netflix.
FLASK APP
# Install Flask
pip install flask flask-sqlalchemy flask-jwt-extended
app = Flask(__name__)
[Link]['SECRET_KEY'] = 'your-secret-key'
# Route: GET /
@[Link]('/')
def index():
return "<h1>Hello from Flask!</h1>"
# POST route
@[Link]('/users', methods=['POST'])
def create_user():
data = request.get_json()
if not [Link]('email'):
return jsonify({'error': 'Email required'}), 400
user = User(name=data["name"], email=data["email"])
[Link](user)
[Link]()
return jsonify(user.to_dict()), 201
if __name__ == '__main__':
[Link](debug=True)
For production Flask apps, use the Application Factory pattern. This separates concerns into
Blueprints and makes testing, configuration, and scaling much easier.
project/
■■■ app/
■ ■■■ auth/
■ ■■■ api/
■■■ [Link]
■■■ [Link]
FLASK FACTORY
db = SQLAlchemy()
jwt = JWTManager()
def create_app(config="[Link]"):
app = Flask(__name__)
[Link].from_object(config)
db.init_app(app)
jwt.init_app(app)
# Register blueprints
from [Link] import auth_bp
from [Link] import api_bp
app.register_blueprint(auth_bp, url_prefix='/auth')
app.register_blueprint(api_bp, url_prefix='/api/v1')
return app
# app/api/[Link] — Blueprint
from flask import Blueprint
api_bp = Blueprint("api", __name__)
@api_bp.route('/products')
def get_products():
products = [Link]()
return jsonify([p.to_dict() for p in products])
Chapter 16
SQLALCHEMY MODELS
db = SQLAlchemy()
id = [Link]([Link], primary_key=True)
username = [Link]([Link](80), unique=True, nullable=False)
email = [Link]([Link](120), unique=True, nullable=False)
password_h = [Link]([Link](256), nullable=False)
is_active = [Link]([Link], default=True)
created_at = [Link]([Link], default=lambda: [Link]([Link]))
# Relationship (one-to-many)
posts = [Link]("Post", back_populates="author",
cascade="all, delete-orphan")
def to_dict(self):
return {"id": [Link], "username": [Link],
"email": [Link], "created_at": str(self.created_at)}
def __repr__(self):
return f"<User {[Link]}>"
SQLALCHEMY QUERIES
# ■■ CREATE ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
user = User(username="alice", email="alice@[Link]")
[Link](user)
[Link]()
# Complex filter
from sqlalchemy import or_, and_
users = [Link](
and_(User.is_active==True, [Link]("%@[Link]"))
).order_by(User.created_at.desc()).limit(10).all()
# ■■ UPDATE ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
user = [Link].get_or_404(1)
[Link] = "newemail@[Link]"
[Link]()
# ■■ DELETE ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
user = [Link].get_or_404(1)
[Link](user)
[Link]()
# ■■ Pagination ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
page = [Link]("page", 1, type=int)
users = [Link](page=page, per_page=20)
# [Link] / [Link] / [Link]
Chapter 18
Protected Verify
Request Token
JWT AUTH
@auth_bp.route('/register', methods=['POST'])
def register():
data = request.get_json()
if [Link].filter_by(email=data["email"]).first():
return jsonify({'error': 'Email already exists'}), 409
user = User(
username = data["username"],
email = data["email"],
password_h= generate_password_hash(data["password"])
)
[Link](user); [Link]()
return jsonify({'message': 'User created'}), 201
@auth_bp.route('/login', methods=['POST'])
def login():
data = request.get_json()
user = [Link].filter_by(email=data["email"]).first()
if not user or not check_password_hash(user.password_h, data["password"]):
return jsonify({'error': 'Invalid credentials'}), 401
access = create_access_token(identity=[Link])
refresh = create_refresh_token(identity=[Link])
return jsonify({'access_token': access, 'refresh_token': refresh})
# Protected route
@auth_bp.route('/me', methods=['GET'])
@jwt_required()
def get_me():
user_id = get_jwt_identity()
user = [Link].get_or_404(user_id)
return jsonify(user.to_dict())
PART 4
DJANGO
The Full-Featured Python Web Framework
Chapter 20
Django is a high-level Python web framework that follows the "batteries included" philosophy. It
includes an ORM, admin panel, authentication, template engine, form handling, and security features
out of the box. Django powers Instagram, Disqus, Mozilla, and Bitbucket.
VIEW
Templates &
UI Layer
MODEL
Database &
Business Logic
CONTROLLER
Route Handlers
& Logic
DJANGO SETUP
# Install Django
pip install django djangorestframework django-environ
# Project structure
mysite/
■■■ [Link]
■■■ mysite/
■ ■■■ [Link] # Configuration
■ ■■■ [Link] # Root URL router
■ ■■■ [Link] # WSGI entry point
■■■ blog/
■■■ [Link] # Database models
■■■ [Link] # Request handlers
■■■ [Link] # App URL patterns
■■■ [Link] # DRF serializers
■■■ [Link] # Admin config
■■■ templates/
■■■ blog/
■■■ [Link]
DJANGO SETTINGS
env = [Link]()
[Link].read_env() # reads .env file
SECRET_KEY = env('SECRET_KEY')
DEBUG = [Link]('DEBUG', default=False)
ALLOWED_HOSTS = [Link]('ALLOWED_HOSTS', default=['*'])
INSTALLED_APPS = [
'[Link]',
'[Link]',
'[Link]',
'rest_framework', # DRF
'blog', # our app
]
DATABASES = {
'default': [Link]('DATABASE_URL',
default='sqlite:///db.sqlite3')
}
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
Chapter 21
DJANGO MODELS
# blog/[Link]
from [Link] import models
from [Link] import User
from [Link] import slugify
class Category([Link]):
name = [Link](max_length=100, unique=True)
slug = [Link](unique=True)
class Meta:
verbose_name_plural = "categories"
ordering = ["name"]
class Post([Link]):
STATUS_CHOICES = [("draft","Draft"),("published","Published")]
title = [Link](max_length=250)
slug = [Link](unique=True)
author = [Link](User, on_delete=[Link],
related_name="post
category = [Link](Category, on_delete=models.SET_NULL,
null=True, related
body = [Link]()
thumbnail = [Link](upload_to="posts/%Y/%m/%d/", blank=True)
status = [Link](max_length=10, choices=STATUS_CHOICES,
default="draft")
created_at = [Link](auto_now_add=True)
updated_at = [Link](auto_now=True)
published = [Link](null=True, blank=True)
tags = [Link]("Tag", blank=True)
class Meta:
ordering = ["-created_at"]
indexes = [[Link](fields=["-created_at"])]
DJANGO ORM
# CREATE
post = [Link](title="Hello World",
slug="hello-world", author=user, body="Content...")
# READ
post = [Link](id=1)
posts = [Link]()
posts = [Link](status="published")
posts = [Link](author__username="alice") # follow FK
count = [Link](status="published").count()
# Chaining queries
posts = ([Link]
.filter(status="published")
.select_related("author", "category") # JOIN — avoid N+1
.prefetch_related("tags") # prefetch M2M
.order_by("-published")
[:10]) # LIMIT 10
# UPDATE
[Link](status="draft").update(status="published")
# DELETE
[Link](created_at__year=2020).delete()
# Aggregation
from [Link] import Count, Avg, Max
stats = [Link](total=Count("id"), avg_len=Avg("body"))
Chapter 23
DRF SERIALIZER
# blog/[Link]
from rest_framework import serializers
from .models import Post, Category
class CategorySerializer([Link]):
post_count = [Link](read_only=True)
class Meta:
model = Category
fields = ['id', 'name', 'slug', 'post_count']
class PostSerializer([Link]):
author_name = [Link](source="[Link]",
read_on
category = CategorySerializer(read_only=True)
category_id = [Link](write_only=True)
class Meta:
model = Post
fields = ['id','title','slug','body','status',
'author_name','category','category_id','created_at']
read_only_fields = ['slug','created_at']
DRF VIEWSET
# blog/[Link]
from rest_framework import viewsets, permissions, filters
from rest_framework.decorators import action
from rest_framework.response import Response
from [Link] import Count
from .models import Post
from .serializers import PostSerializer
class PostViewSet([Link]):
queryset = [Link].select_related("author","category").annotate(
comment_count=Count("comments"))
serializer_class = PostSerializer
permission_classes = [[Link]]
filter_backends = [[Link], [Link]]
search_fields = ["title", "body"]
ordering_fields= ["created_at", "title"]
def get_queryset(self):
qs = super().get_queryset()
status = [Link].query_params.get("status")
return [Link](status=status) if status else qs
# blog/[Link]
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
[Link](r'posts', PostViewSet)
urlpatterns = [Link]
# Generates: GET/POST /posts/, GET/PUT/PATCH/DELETE /posts/{id}/
PART 5
FASTAPI
Modern High-Performance Async Python APIs
Chapter 26
FastAPI is the fastest-growing Python web framework. It is built on ASGI (async), uses Python type
hints for automatic validation, generates OpenAPI docs automatically, and is as fast as [Link]/Go. It
is the modern choice for building APIs.
FASTAPI APP
# Install
pip install fastapi uvicorn[standard] sqlalchemy
app = FastAPI(
title="My API",
version="1.0.0",
description="Full-featured REST API"
)
class UserCreate(UserBase):
password : str
@validator("password")
def strong_password(cls, v):
if len(v) < 8: raise ValueError("Min 8 chars")
return v
class UserResponse(UserBase):
id : int
created_at : datetime
class Config: from_attributes = True
@[Link]("/users/{user_id}", response_model=UserResponse)
async def get_user(user_id: int, db = Depends(get_db)):
user = [Link](User).filter([Link] == user_id).first()
if not user: raise HTTPException(404, "User not found")
return user
FASTAPI PARAMETERS
# Request body
@[Link]("/users", response_model=UserResponse, status_code=201)
async def create_user(
user: UserCreate, # Automatic validation!
db = Depends(get_db)
):
existing = [Link](User).filter([Link]==[Link]).first()
if existing: raise HTTPException(409, "Email taken")
db_user = User(**[Link]())
db_user.password = hash_password([Link])
[Link](db_user); [Link](); [Link](db_user)
return db_user
PART 6
DATABASES
SQL, PostgreSQL, Redis & MongoDB
Chapter 31
SQL
-- Aggregations
SELECT dept, COUNT(*) as total, AVG(salary) as avg_sal
FROM employees
GROUP BY dept
HAVING COUNT(*) > 5;
POSTGRESQL
-- Partial index
CREATE INDEX idx_active_users ON users(email) WHERE is_active=TRUE;
PART 7
DEPLOYMENT
Docker, CI/CD, Cloud & Production
Chapter 37
DOCKERFILE
# ■■ Dockerfile ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
FROM python:3.11-slim
# Expose port
EXPOSE 8000
# Health check
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f [Link] || exit 1
DOCKER COMPOSE
# ■■ [Link] ■■■■■■■■■■■■■■■■■■■■■■■
version: "3.9"
services:
web:
build: .
ports: ["8000:8000"]
env_file: .env
depends_on:
db:
condition: service_healthy
volumes:
- ./media:/app/media
restart: unless-stopped
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASS}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
ports: ["6379:6379"]
nginx:
image: nginx:alpine
ports: ["80:80", "443:443"]
volumes:
- ./[Link]:/etc/nginx/conf.d/[Link]
- ./static:/app/static
volumes:
postgres_data:
■ NOTE
Always use a .dockerignore file to exclude __pycache__, .git, .env, node_modules,
and other files that should not be in the image. This keeps images small and
secure.
Chapter 40
■ PROJECT
Build a complete task management REST API with FastAPI + PostgreSQL + Redis + JWT
Auth + Docker. This project demonstrates production-ready patterns.
PROJECT STRUCTURE
[Link].create_all(bind=engine)
# CORS
app.add_middleware(CORSMiddleware,
allow_origins=["[Link] "[Link]
allow_credentials=True, allow_methods=["*"], allow_headers=["*"])
# Routers
app.include_router([Link], prefix='/api/v1/auth', tags=['Auth'])
app.include_router([Link], prefix='/api/v1/users', tags=['Users'])
app.include_router([Link], prefix='/api/v1/tasks', tags=['Tasks'])
@[Link]('/health')
async def health(): return {"status": "ok"}
Python, Django/Flask,
Backend Dev $110K–145K Google, Amazon, Stripe
SQL
FastAPI, gRPC,
API Engineer $120K–160K Uber, Netflix, Twilio
microservices
DevOps Engineer Docker, K8s, CI/CD, AWS $125K–170K Any tech company
■ TIP
The best portfolio shows problem-solving. Build apps that solve real problems you
have — a budget tracker, workout logger, recipe manager — not just todo lists or
weather apps.