
The definitive Django guide that revolutionized web development practices. Endorsed by Python community leaders and shaped by Malcolm Tredinnick's legendary influence, this book has become the secret weapon for developers worldwide. Why do Django experts consider it mandatory reading before touching production code?
from django.forms import * to prevent namespace pollution and hidden bugs.select_related/prefetch_related methods.python-dotenv for secrets.Daniel Roy Greenfeld and Audrey Roy Greenfeld are the acclaimed co-authors of Two Scoops of Django: Best Practices for Django 3.x, recognized as essential reading for Python/Django developers worldwide. As seasoned software engineers and open-source contributors, they combine decades of technical expertise with a knack for transforming complex concepts into actionable guidance. Their ice cream-themed technical guide—praised for its accessible tone and practical approach—has become a staple for developers refining Django project architecture, security, and scalability.
Daniel, known as "PyDanny" in the developer community, also writes fantasy novels like Into the Brambles and the Ambria series, blending mythological influences with intricate worldbuilding. Audrey, a frequent conference speaker, co-founded the Django Packages resource directory. Together, they maintain the Feldroy blog and contribute to Django REST Framework documentation.
Two Scoops of Django has sold tens of thousands of copies across multiple editions since 2013, consistently ranking among the top Django books on technical platforms. Their work is cited in official Django documentation and recommended by core framework contributors.
Two Scoops of Django by Daniel and Audrey Roy Greenfeld is a comprehensive guide to Django best practices, offering actionable advice for building maintainable projects. It uses a fictional ice cream company case study to illustrate concepts like project structure, ORM optimization, security, testing, and deployment. The 500-page book covers 35+ topics, including Django REST Framework, async tasks, and third-party package integration.
This book targets intermediate Django developers familiar with the framework’s basics but seeking to adopt industry-standard patterns. It’s ideal for engineers refining project architecture, teams enforcing coding standards, or developers preparing scalable applications for production.
Yes, the book is highly recommended for its practical, example-driven approach to Django best practices. Reviewers praise its coverage of real-world scenarios, anti-pattern avoidance, and updated editions aligning with Django versions. The blend of humor and structured guidance makes complex concepts accessible.
Daniel and Audrey Roy Greenfeld are Django experts with extensive industry experience, including roles at NASA and open-source contributions. Their combined technical expertise and teaching focus ensure the book’s balance of depth and readability.
The book emphasizes “fat models, thin views, stupid templates,” project structure standardization, and environment-specific settings management. It advocates for explicit over implicit code, secure deployment configurations, and systematic testing strategies. Anti-pattern examples like hardcoded paths or wildcard imports are highlighted as pitfalls to avoid.
It recommends modular app design, segregated settings files (e.g., base.py, production.py), and requirements.txt organization. The authors discourage placing virtual environments inside project folders and promote reusable utility modules over bloated views.
The book covers unit testing, integration testing, and tools like pytest-django. It stresses test isolation, mocking external APIs, and leveraging Django’s test client for web request simulation. Testing anti-patterns like overscoped test cases are critiqued.
Security practices include CSRF protection, XSS mitigation via template autoescaping, and proper cookie configuration. The book advises against storing secrets in version control and demonstrates HTTPS setup, password hashing, and permission management.
Deployment chapters detail server configuration (e.g., Gunicorn/Nginx), database optimization, and CI/CD pipelines. The authors emphasize monitoring, logging, and error-tracking tools like Sentry. Cloud platforms (AWS, Heroku) and containerization basics are also addressed.
It provides patterns for API versioning, serializer validation, and authentication (JWT/OAuth). The authors recommend throttling for rate limits, Swagger/OpenAPI documentation, and client-library integration tips. Common pitfalls like N+1 queries in serializers are discussed.
Some reviewers note the book’s density and occasional whitespace inefficiency. However, these are outweighed by its practicality, with most considering it indispensable post-official-tutorial material. The structured examples and humor are widely praised.
Each edition updates examples and recommendations for newer Django releases (e.g., 1.11 vs 3.x). The 3.x version expands async support, Django REST Framework enhancements, and modern tooling (Docker, GitHub Actions). Core principles remain consistent, making prior editions useful for legacy projects.
저자의 목소리로 책을 느껴보세요
핵심 아이디어를 빠르게 캡처하여 신속하게 학습
Writing clear, consistent code makes maintenance easier.
Always use version control for Django projects.
Docker lets you quickly set up environments matching production configurations.
Smaller, focused apps are easier to maintain, test, and reuse than large ones.
무엇이든 묻고, 학습 스타일을 선택하고, 나에게 맞는 인사이트를 함께 만들어보세요.

샌프란시스코에서 컬럼비아 대학교 동문들이 만들었습니다
"Instead of endless scrolling, I just hit play on BeFreed. It saves me so much time."
"I never knew where to start with nonfiction—BeFreed’s book lists turned into podcasts gave me a clear path."
"Perfect balance between learning and entertainment. Finished ‘Thinking, Fast and Slow’ on my commute this week."
"Crazy how much I learned while walking the dog. BeFreed = small habits → big gains."
"Reading used to feel like a chore. Now it’s just part of my lifestyle."
"Feels effortless compared to reading. I’ve finished 6 books this month already."
"BeFreed turned my guilty doomscrolling into something that feels productive and inspiring."
"BeFreed turned my commute into learning time. 20-min podcasts are perfect for finishing books I never had time for."
"BeFreed replaced my podcast queue. Imagine Spotify for books — that’s it. 🙌"
"It is great for me to learn something from the book without reading it."
"The themed book list podcasts help me connect ideas across authors—like a guided audio journey."
"Makes me feel smarter every time before going to work"
샌프란시스코에서 컬럼비아 대학교 동문들이 만들었습니다

Two Scoops of Django 요약을 무료 PDF 또는 EPUB으로 받으세요. 인쇄하거나 오프라인에서 언제든 읽을 수 있습니다.
In a world where web frameworks come and go, Django has remained a steadfast pillar of Python web development for over a decade. "Two Scoops of Django" by Daniel Roy Greenfeld and Audrey Roy Greenfeld has become the unofficial bible for Django developers worldwide, with copies adorning the desks of everyone from solo developers to engineering teams at companies like Instagram and Pinterest. This beloved guide, playfully themed around ice cream, delivers a comprehensive collection of Django best practices that have been battle-tested in production environments. As Guido van Rossum, creator of Python, noted: "This book distills years of Django wisdom into actionable advice that will make you a more effective developer overnight."
Django projects, like any software endeavor, live or die by the quality of their code. The authors emphasize that code is read far more often than it's written, making readability paramount. "Writing clear, consistent code makes maintenance easier," they explain, advocating for descriptive variable names, proper documentation, and thoughtful refactoring of repeated code. The book strongly recommends following Python's PEP 8 style guide, which establishes conventions like using 4 spaces for indentation, separating top-level functions with two blank lines, and class methods with single blank lines. While some developers balk at the 79-character line limit, the authors suggest a practical compromise: "Adhere to 79 characters for open source projects but relax to 99 for private projects." Import statements deserve special attention, as they provide a roadmap of dependencies. The recommended organization follows a clear hierarchy: standard library imports first, core Django imports next, third-party app imports, and finally imports from your own Django apps. This simple pattern makes code more navigable and dependencies more obvious. "Explicit relative imports make code more portable and easier to maintain," the authors advise. Using explicit imports like `from .models import Flavor` rather than `from cones.models import Flavor` makes apps more reusable and portable. This approach also visually distinguishes local imports from external ones, highlighting the Python package as a cohesive unit. The authors warn against using wildcard imports (`from module import *`), which can cause unpredictable name collisions. When two modules contain classes with identical names, explicit imports with aliases provide clarity: `from django.db.models import CharField as ModelCharField` and `from django.forms import CharField as FormCharField`. Beyond Python, the book recommends establishing consistent coding styles for JavaScript, HTML, and CSS as well. "Unlike Python, JavaScript has no single official style guide," they note, suggesting options like Standard, idiomatic.js, or Airbnb's guide. The key is selecting one and applying it consistently throughout your project.
A properly configured development environment prevents countless headaches down the road. The authors emphasize using the same database engine across all environments to avoid subtle bugs caused by differences in SQL dialects, data types, and constraints. "You can't examine exact copies of production data locally when development and production databases differ," they explain. Different databases handle field typing differently-SQLite uses weak typing while PostgreSQL enforces strong typing-meaning constraints that pass in development might fail in production. Virtual environments are essential for isolating project dependencies. The authors recommend virtualenv with virtualenvwrapper, which simplifies environment management with commands like `workon twoscoops` instead of lengthy path references. For dependency management, pip combined with requirements files ensures consistent installations across environments. Version control is non-negotiable. "Always use version control for Django projects," the authors insist, recommending Git for its popularity among Django, Python, and JavaScript developers. Beyond local repositories, code hosting services like GitHub or GitLab provide essential backup and collaboration capabilities. For teams seeking environment consistency, Docker has become the industry standard. "Docker lets you quickly set up environments matching production configurations," they explain. Using Docker Compose, teams can ensure consistent development environments regardless of local operating system, though this approach adds complexity and potential performance overhead.
How you organize your Django project has profound implications for its maintainability. The book presents a modified project structure that separates configuration from application code and provides clear locations for documentation, deployment files, and other components. The recommended structure includes three key levels: 1. **Repository Root**: Contains high-level project files like README.md, .gitignore, and directories for documentation, requirements, and deployment configurations. 2. **Django Project Root**: Houses the actual Django code, including apps, static files, media files, and templates. 3. **Configuration Root**: Contains settings files, URL configurations, and WSGI application definitions. This organization scales better for complex projects than Django's default layout, which becomes limiting as projects grow, particularly in handling configuration across different environments. For managing settings, the authors recommend splitting them into logical modules (base, local, test, production) to maintain organization while allowing environment-specific configurations. "This approach keeps settings DRY and makes differences between environments explicit," they explain. Sensitive information like passwords and API keys should be kept out of your codebase using environment variables or secure external configuration systems, following the principles of the Twelve-Factor App methodology. When environment variables aren't practical, alternatives include JSON files, .env files, or other structured formats kept outside version control. Similarly, Python dependencies should be organized into multiple requirements files based on their purpose (base, development, production, testing) to keep environments lean and properly configured for their specific needs.
Django's app system encourages modular, reusable code, but requires thoughtful design. The authors present a golden rule: "Each app should be focused on a single, well-defined function." This approach creates components that can be easily maintained and potentially shared across projects. They illustrate proper app design with an ice cream store example, showing how to divide functionality into focused apps like "flavors" for managing ice cream types and "toppings" for managing available toppings. This separation creates cleaner, more maintainable code than a single monolithic app. App names should be short, descriptive nouns in plural form (e.g., "accounts" rather than "account"). Clear, consistent naming makes projects more intuitive and helps developers quickly understand an app's purpose without examining its code. When apps grow too complex, the authors recommend splitting them into smaller components. "Smaller, focused apps are easier to maintain, test, and reuse than large ones with multiple responsibilities," they explain. If an app becomes too complex or handles multiple concerns, it should be divided into more focused pieces. Common modules in Django apps include models.py for database models, views.py for view functions or classes, urls.py for URL patterns, forms.py for form classes, and admin.py for admin configurations. As apps grow, additional modules may be needed for specific functionality like API views, custom template tags, or background tasks.
Models form the foundation of most Django projects, defining both the database structure and much of the business logic. The authors advocate for "Fat Models" that encapsulate data-related logic in model methods, classmethods, and properties rather than spreading it across views and templates. However, they warn against models becoming "god objects"-thousands of lines of code that become hard to understand, test, and maintain. When models grow unwieldy, consider isolating reusable code into Model Behaviors (mixins) or Stateless Helper Functions. The book offers practical advice on model design, recommending that apps with more than 20 models should probably be broken into smaller apps. "In practice, we recommend no more than five models per app," they suggest, keeping each app focused and manageable. For model inheritance, Django offers three approaches: abstract base classes, multi-table inheritance, and proxy models. The authors strongly recommend against multi-table inheritance due to performance issues: "Use explicit OneToOneFields and ForeignKeys to control when joins occur," they advise. A common pattern they recommend is using abstract base classes for shared functionality like timestamps: This approach gives models timestamp fields without the overhead of multi-table inheritance, as Django won't create a database table for the abstract base class. The book provides detailed guidance on field choices, recommending that developers "start normalized and only denormalize after exploring other options." Often, setting up caching in the right places can save you the trouble of denormalizing your models prematurely.
Django forms provide a powerful system for validating user input, rendering HTML controls, and processing submitted data securely. "Never trust user input," the authors emphasize, recommending Django's form system for all data validation, even for seemingly simple inputs. For forms that modify data, always use the POST method to prevent accidental or malicious changes through URL manipulation. GET should only be used for idempotent operations like search forms where bookmarking results is desirable. CSRF protection is essential for preventing cross-site request forgery attacks. Include the `{% csrf_token %}` tag in all forms that modify data, and when submitting forms via AJAX, include the CSRF token in your request headers using Django's provided JavaScript helpers. Django's form validation happens in multiple stages: field-level validation, clean methods for individual fields, and form-wide validation. Understanding this flow is crucial for implementing complex validation logic correctly. The authors recommend using Form.add_error() to add validation errors programmatically, either field-specific or non-field errors. This provides clear feedback to users while maintaining form state for correction. For specialized input requirements, create custom form fields by extending Django's base field classes and implementing appropriate validation logic. Widgets control how form fields render as HTML, and can be customized to match your design system while maintaining Django's validation capabilities.
Documentation is a critical component of any Django project, serving as both a technical reference and a knowledge transfer tool. Good documentation ensures your code is maintainable, accessible to new team members, and usable by others. It acts as a living document that evolves with your project and serves as the first point of contact for developers trying to understand your codebase. The authors recommend reStructuredText (reST) as the preferred format for Python documentation. Its rich feature set supports semantic markup, cross-referencing, and automatic generation of tables of contents, making it ideal for comprehensive documentation. reST excels at technical documentation with features like code-block directives, admonitions for warnings and notes, and the ability to define custom roles for specialized content. For example, you can create custom roles for API endpoints, database models, or configuration settings. Sphinx transforms reST files into beautiful HTML, PDF, and other formats. It's the standard tool for Python documentation, offering features like autodoc for pulling docstrings directly from code. Sphinx's extensibility allows for custom themes, additional directives, and integration with testing frameworks. The autodoc feature is particularly powerful, automatically generating API documentation from properly formatted docstrings, ensuring documentation stays synchronized with code changes. Every Django project should include several key documentation components: • Detailed installation instructions with environment setup • Configuration details, including environment variables and settings • Comprehensive API documentation with request/response examples • Usage examples and common patterns • Deployment guides for different environments • Troubleshooting guides and FAQs • Contributing guidelines and development setup Well-structured documentation should follow a logical progression from basic to advanced topics, with clear navigation and search capabilities. While reStructuredText is preferred for Python projects, Markdown offers a simpler syntax that's easier to learn and is widely supported by platforms like GitHub. It's particularly useful for README files and simpler documentation needs. Tools like Pandoc can convert between Markdown and reStructuredText, allowing you to maintain a Markdown README for GitHub while providing an RST version for PyPI. This dual-format approach lets you leverage GitHub's rendered Markdown while still maintaining compatibility with Python's documentation ecosystem. Documentation should be treated as a first-class citizen in your development process, with regular reviews and updates as part of your project's maintenance routine. Consider implementing documentation checks in your CI/CD pipeline to ensure documentation coverage and accuracy. Many teams also benefit from establishing documentation templates and style guides to maintain consistency across their documentation.
Performance optimization is crucial for Django applications as they grow. Identifying and addressing bottlenecks ensures your application remains responsive under increasing load. Database queries often represent the biggest performance bottleneck in Django applications. Django Debug Toolbar reveals the SQL queries executed for each request, helping identify N+1 query problems and other inefficiencies that might otherwise go unnoticed. Using select_related() and prefetch_related() can dramatically reduce query counts by fetching related objects in fewer database hits, turning potentially hundreds of queries into just a few. Strategic indexing, query optimization, and denormalization when necessary can significantly improve the performance of frequently-run queries. Not all data belongs in your primary database. Large binary files, logs, and other non-relational data may be better stored elsewhere to maintain database performance. Different database engines also have their own optimization techniques-PostgreSQL offers powerful features like JSON fields and full-text search, while MySQL has its own configuration settings that can significantly improve performance when properly tuned. Implementing caching with Memcached or Redis can dramatically reduce database load by storing frequently accessed data in memory. Strategic caching of expensive computations, template fragments, and entire views can provide substantial performance improvements while minimizing complexity. Reducing the size of your static assets through compression and minification decreases page load times and bandwidth usage. CDNs and upstream caching can dramatically improve performance by serving static content from locations closer to your users and reducing the load on your application servers.
Debugging is inevitable in both new and legacy Django projects. Django Debug Toolbar is invaluable for displaying detailed information about the current request/response cycle, showing template rendering speed, database queries, and variables in use. When using Class-Based Views, a common error appears as "TypeError: __init__() takes exactly 1 argument (2 given)" in the console. This happens when developers forget to add the .as_view() method to their CBV routing in urls.py. PDB (Python Debugger) provides an enhanced REPL for interacting with code at specified breakpoints. The ipdb package extends PDB with ipython's interface, making it even more powerful. Remember to check for and remove PDB breakpoints before deployment, as they'll halt user requests in production. For production debugging, consider using error aggregators like Sentry to get a clearer view of what's happening in your application. Creating a mirror of your production environment behind a firewall, with sanitized production data, allows you to replicate reported bugs in a safe environment. Feature flags allow turning project features on or off via a web interface. They let you expose new features to a subset of users before full release, catching production problems early with beta users willing to try potentially buggy features.
Django provides comprehensive security features that protect against common web vulnerabilities. The framework includes multiple layers of built-in protection: XSS (Cross-Site Scripting) prevention through automatic HTML escaping, CSRF (Cross-Site Request Forgery) middleware that validates form submissions, SQL injection protection via parameterized queries, and clickjacking prevention through X-Frame-Options headers. Password storage uses the robust PBKDF2 algorithm with SHA256 hash, and Django's serialization tools are hardened against malicious data. While most security features work automatically, some require specific configuration in your settings.py file. Debug mode is a critical security concern in production environments. Never deploy with DEBUG = True, as this exposes sensitive information through detailed error pages and stack traces that attackers can use to understand your application architecture. Your SECRET_KEY must remain confidential and should be stored in environment variables or secure configuration files, not in version control. A compromised SECRET_KEY can lead to session hijacking, remote code execution, and password reset token exploitation. HTTPS deployment is essential for modern web applications. Configure your web server (nginx, Apache) to redirect all HTTP traffic to HTTPS. Enable strict transport security (HSTS) headers to prevent downgrade attacks. In Django settings, enable SESSION_COOKIE_SECURE and CSRF_COOKIE_SECURE to True, and consider setting SECURE_SSL_REDIRECT = True. Additionally, configure SESSION_COOKIE_HTTPONLY = True to prevent JavaScript access to session cookies. Form handling requires careful attention to prevent mass assignment vulnerabilities. When using ModelForms, explicitly declare allowed fields using Meta.fields = ['field1', 'field2']. Avoid Meta.exclude or Meta.fields = "__all__" as they can accidentally expose sensitive fields to modification. For extra security, implement field-level permissions and validate form data thoroughly using clean() methods. Payment processing demands extra security measures. Unless you can fully implement and maintain PCI-DSS compliance (which involves extensive security controls and regular audits), use established payment processors. Services like Stripe, Braintree, or PayPal handle sensitive card data through secure iframes or API tokens, significantly reducing your security burden and liability. Implement a comprehensive security monitoring strategy. Set up automated log analysis tools to detect suspicious patterns in web server logs. Use tools like fail2ban to block repeated failed login attempts. Configure Django's logging to capture security-related events, and regularly review these logs. Keep all dependencies updated by running 'pip list --outdated' regularly and subscribing to security announcement channels for Django and key packages. Consider implementing Content Security Policy (CSP) headers to prevent XSS attacks and using Django's built-in password validation to enforce strong password policies.
Django deployment is a complex topic with multiple approaches. For small projects, single-server deployment is the quickest and cheapest option, though it risks downtime during traffic spikes. Multi-server setups separate database, WSGI application, static files, and caching onto different servers, allowing components to be optimized, scaled, or replaced individually. Always deploy Django projects with WSGI. The most common WSGI deployment setups are uWSGI with Nginx (feature-rich but complex), Gunicorn behind Nginx (Python-based, good memory usage), and Apache with mod_wsgi (stable, well-documented, but configuration can be complex). Server configuration should be automated and documented for easy recreation. You should be able to spin up your entire server setup with a single command, without manual intervention. Scripts should be idempotent, producing identical results regardless of how many times they're run. For small side projects or startups, Platform as a Service (PaaS) providers save significant time compared to setting up your own servers. However, it's crucial to avoid getting locked into any single platform, as they can undergo changes that might harm your project through price increases, performance issues, or even going out of business. When evaluating a PaaS, consider compliance requirements, pricing, uptime, staffing, scaling capabilities, HTTP server compatibility, documentation quality, performance, geographic location, and company stability.
Continuous integration is a software development practice where team members frequently integrate their work-at least daily-with each integration verified by automated builds and tests. This approach reduces integration problems and enables faster cohesive software development. Without comprehensive tests, continuous integration lacks its most powerful feature. When tests take too long to run, CI becomes a burden rather than an advantage. Better approaches include avoiding fixtures and TransactionTestCase, minimizing setUp() methods, writing focused tests, and optimizing your database for testing. Each test should focus on one specific behavior-one view, model, form, method or function. Be minimalistic when constructing the test environment, using setUp() to create only the essential records needed. Testing failure scenarios is often more important than testing success. For example, when testing a view that allows users to edit their reviews, we must check what happens when users aren't logged in or try to edit someone else's review. These security tests prevent silent vulnerabilities that could go undetected until exploited. Treating test coverage as a game makes it fun-every day you increase coverage is a victory, every day it decreases is a loss. It's a useful metric for both developers and stakeholders to evaluate project health.
Django's power comes from its vast selection of third-party packages, with thousands of solutions available on the Python Package Index (PyPI). Using pip and virtualenv is essential for managing these packages, creating isolated environments that prevent dependency conflicts and ensure project reproducibility. When evaluating packages, consider maturity (look for version numbers above 1.0), comprehensive documentation, extensive test coverage (aim for >80%), active maintenance, and clean, readable code. Popular packages like django-rest-framework, django-crispy-forms, and django-allauth have set high standards for what to expect. The Django community follows a structured Code of Conduct that ensures spaces like IRC (#django on Freenode), Discord channels, and mailing lists remain welcoming, considerate and respectful environments. This code emphasizes inclusivity, patience with newcomers, and constructive discourse. When stuck on a problem, follow a systematic approach: first troubleshoot independently using debug tools and logging, thoroughly read both Django's documentation and package-specific docs, search GitHub issues and StackOverflow for similar problems, create a minimal reproducible example when asking for help, and if the issue remains unsolved after 2-3 days of investigation, reach out to the django-users mailing list or IRC channel. One of the distinguishing strengths of Django is the human factor of the community behind the framework. The Django Software Foundation actively supports community initiatives, conferences (DjangoCon), and sprints worldwide. When seeking guidance, approach with a friendly, open stance and detailed context about your problem. While community members won't write code for you or solve business logic problems, they'll generally provide technical guidance, suggest approaches, or point you to relevant documentation and resources. Many core developers are regularly active in these spaces, offering deep insights into Django's internals. By following the best practices outlined in "Two Scoops of Django," you'll create maintainable, secure, and performant applications that leverage the full power of Django's ecosystem. This includes using appropriate design patterns, following security best practices, implementing caching strategies, and organizing code in a way that scales. As the authors note, "Django, like ice cream, should be enjoyable"-and with proper techniques and community involvement, it becomes a robust foundation for building modern web applications. The ecosystem continues to evolve with each release, introducing new features while maintaining backwards compatibility, making it a reliable choice for both startups and enterprise applications.