Full-Stack Development with Django and React
Best practices for building modern web applications with Django REST Framework backend and React frontend. Architecture patterns from my experience at multiple startups.
Why Django + React?
After building applications with various stack combinations, Django + React remains my go-to choice for startups. Here's why:
Django's Strengths
React's Strengths
Project Structure
Here's the structure I use for most projects:
project/
├── backend/
│ ├── apps/
│ │ ├── users/
│ │ ├── core/
│ │ └── api/
│ ├── config/
│ └── requirements/
├── frontend/
│ ├── src/
│ │ ├── components/
│ │ ├── pages/
│ │ ├── hooks/
│ │ └── services/
│ └── package.json
└── docker-compose.yml
API Design Patterns
Serializers
Keep serializers focused. Create different serializers for different use cases:
class UserListSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'username', 'avatar']
class UserDetailSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'username', 'email', 'bio', 'created_at']
ViewSets
Use ViewSets for standard CRUD operations, but don't force everything into ViewSets.
Frontend Patterns
API Service Layer
Abstract your API calls:
// services/api.ts
export const userService = {
getAll: () => api.get('/users/'),
getById: (id: string) => api.get(`/users/${id}/`),
update: (id: string, data: UserUpdate) => api.patch(`/users/${id}/`, data),
};
Custom Hooks
Encapsulate data fetching logic:
function useUser(id: string) {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
userService.getById(id)
.then(setUser)
.finally(() => setLoading(false));
}, [id]);
return { user, loading };
}
Lessons from Production
At Seleda (28K+ users)
At Juniper (3000+ users in week one)
Conclusion
Django + React isn't the only valid stack, but it's a reliable one. The key is understanding the patterns and applying them consistently.