[{"data":1,"prerenderedAt":2232},["ShallowReactive",2],{"navigation":3,"/testing":1016,"/testing-surround":2227},[4,54,89,123,165,211,253,331,389,439,462,488,514,540,578,624,650,672,702,736,774,800,850,856,862,868,874,928],{"title":5,"path":6,"stem":7,"children":8},"Introduction and Foundations","/introduction-and-foundations","01.introduction-and-foundations/01.index",[9,10,14,18,22,26,30,34,38,42,46,50],{"title":5,"path":6,"stem":7},{"title":11,"path":12,"stem":13},"What is Django","/introduction-and-foundations/what-is-django","01.introduction-and-foundations/02.what-is-django",{"title":15,"path":16,"stem":17},"Key Concepts and Philosophy","/introduction-and-foundations/key-concepts-and-philosophy","01.introduction-and-foundations/03.key-concepts-and-philosophy",{"title":19,"path":20,"stem":21},"MVC vs MVT: Understanding Django's Architecture","/introduction-and-foundations/mvc-vs-mvt","01.introduction-and-foundations/04.mvc-vs-mvt",{"title":23,"path":24,"stem":25},"Project Structure Overview","/introduction-and-foundations/project-structure-overview","01.introduction-and-foundations/05.project-structure-overview",{"title":27,"path":28,"stem":29},"Installing Django","/introduction-and-foundations/installing-django","01.introduction-and-foundations/06.installing-django",{"title":31,"path":32,"stem":33},"Creating Your First Django Project","/introduction-and-foundations/creating-first-project","01.introduction-and-foundations/07.creating-first-project",{"title":35,"path":36,"stem":37},"Creating Your First Django App","/introduction-and-foundations/creating-first-app","01.introduction-and-foundations/08.creating-first-app",{"title":39,"path":40,"stem":41},"Your First Django \"Hello World\"","/introduction-and-foundations/hello-world","01.introduction-and-foundations/09.hello-world",{"title":43,"path":44,"stem":45},"Django Quick Start Guide","/introduction-and-foundations/quick-start-guide","01.introduction-and-foundations/10.quick-start-guide",{"title":47,"path":48,"stem":49},"How Django Handles Requests","/introduction-and-foundations/how-django-handles-requests","01.introduction-and-foundations/11.how-django-handles-requests",{"title":51,"path":52,"stem":53},"Django Settings","/introduction-and-foundations/django-settings","01.introduction-and-foundations/12.django-settings",{"title":55,"path":56,"stem":57,"children":58},"The Development Environment","/development-environment","02.development-environment/1.index",[59,61,65,69,73,77,81,85],{"title":60,"path":56,"stem":57},"Development Environment",{"title":62,"path":63,"stem":64},"Recommended Tooling for Django Development","/development-environment/recommended-tooling","02.development-environment/2.recommended-tooling",{"title":66,"path":67,"stem":68},"Virtual Environments","/development-environment/virtual-environments","02.development-environment/3.virtual-environments",{"title":70,"path":71,"stem":72},"Django Admin and Management Commands","/development-environment/admin-and-management-commands","02.development-environment/4.admin-and-management-commands",{"title":74,"path":75,"stem":76},"Django Project Settings","/development-environment/project-settings","02.development-environment/5.project-settings",{"title":78,"path":79,"stem":80},"Managing Django Environments: Local, Staging, and Production","/development-environment/environments-local-staging-production","02.development-environment/6.environments-local-staging-production",{"title":82,"path":83,"stem":84},"Running Django Development Server","/development-environment/running-development-server","02.development-environment/7.running-development-server",{"title":86,"path":87,"stem":88},"Working with Django Shell","/development-environment/working-with-shell","02.development-environment/8.working-with-shell",{"title":90,"path":91,"stem":92,"children":93},"Templates and Presentation Layer","/templates-and-presentation","03.templates-and-presentation/1.index",[94,95,99,103,107,111,115,119],{"title":90,"path":91,"stem":92},{"title":96,"path":97,"stem":98},"Introduction to Django Templates","/templates-and-presentation/introduction-to-templates","03.templates-and-presentation/2.introduction-to-templates",{"title":100,"path":101,"stem":102},"The Django Template Language","/templates-and-presentation/django-template-language","03.templates-and-presentation/3.django-template-language",{"title":104,"path":105,"stem":106},"Template Inheritance","/templates-and-presentation/template-inheritance","03.templates-and-presentation/4.template-inheritance",{"title":108,"path":109,"stem":110},"Built-in Template Tags and Filters","/templates-and-presentation/built-in-template-tags-and-filters","03.templates-and-presentation/5.built-in-template-tags-and-filters",{"title":112,"path":113,"stem":114},"Including Static Files","/templates-and-presentation/including-static-files","03.templates-and-presentation/6.including-static-files",{"title":116,"path":117,"stem":118},"Working with Media Files","/templates-and-presentation/working-with-media-files","03.templates-and-presentation/7.working-with-media-files",{"title":120,"path":121,"stem":122},"Using Alternative Template Engines","/templates-and-presentation/using-alternative-template-engines","03.templates-and-presentation/8.using-alternative-template-engines",{"title":124,"path":125,"stem":126,"children":127},"URLs and Views","/urls-and-views","04.urls-and-views/01.index",[128,129,133,137,141,145,149,153,157,161],{"title":124,"path":125,"stem":126},{"title":130,"path":131,"stem":132},"The URL Dispatcher","/urls-and-views/the-url-dispatcher","04.urls-and-views/02.the-url-dispatcher",{"title":134,"path":135,"stem":136},"Writing Function-Based Views","/urls-and-views/writing-function-based-views","04.urls-and-views/03.writing-function-based-views",{"title":138,"path":139,"stem":140},"View Decorators","/urls-and-views/view-decorators","04.urls-and-views/04.view-decorators",{"title":142,"path":143,"stem":144},"Rendering Responses","/urls-and-views/rendering-responses","04.urls-and-views/05.rendering-responses",{"title":146,"path":147,"stem":148},"Redirects","/urls-and-views/redirects","04.urls-and-views/06.redirects",{"title":150,"path":151,"stem":152},"Handling HTTP Methods","/urls-and-views/handling-http-methods","04.urls-and-views/07.handling-http-methods",{"title":154,"path":155,"stem":156},"Conditional View Processing","/urls-and-views/conditional-view-processing","04.urls-and-views/08.conditional-view-processing",{"title":158,"path":159,"stem":160},"File Uploads","/urls-and-views/file-uploads","04.urls-and-views/09.file-uploads",{"title":162,"path":163,"stem":164},"Using Django Shortcut Functions","/urls-and-views/using-django-shortcut-functions","04.urls-and-views/10.using-django-shortcut-functions",{"title":166,"path":167,"stem":168,"children":169},"Class Based Views","/class-based-views","05.class-based-views/01.index",[170,171,175,179,183,187,191,195,199,203,207],{"title":166,"path":167,"stem":168},{"title":172,"path":173,"stem":174},"Introduction to Class-Based Views","/class-based-views/introduction-to-class-based-views","05.class-based-views/02.introduction-to-class-based-views",{"title":176,"path":177,"stem":178},"Common Base Classes","/class-based-views/common-base-classes","05.class-based-views/03.common-base-classes",{"title":180,"path":181,"stem":182},"Built-in Generic Views","/class-based-views/built-in-generic-views","05.class-based-views/04.built-in-generic-views",{"title":184,"path":185,"stem":186},"Views for CRUD Operations","/class-based-views/views-for-crud-operations","05.class-based-views/05.views-for-crud-operations",{"title":188,"path":189,"stem":190},"Handling Forms with Class-Based Views","/class-based-views/handling-forms-with-class-based-views","05.class-based-views/06.handling-forms-with-class-based-views",{"title":192,"path":193,"stem":194},"Using Mixins","/class-based-views/using-mixins","05.class-based-views/07.using-mixins",{"title":196,"path":197,"stem":198},"URL Configuration with Class-Based Views","/class-based-views/url-configuration-with-class-based-views","05.class-based-views/08.url-configuration-with-class-based-views",{"title":200,"path":201,"stem":202},"Subclassing Generic Views","/class-based-views/subclassing-generic-views","05.class-based-views/09.subclassing-generic-views",{"title":204,"path":205,"stem":206},"Asynchronous Class-Based Views","/class-based-views/asynchronous-class-based-views","05.class-based-views/10.asynchronous-class-based-views",{"title":208,"path":209,"stem":210},"Pagination","/class-based-views/pagination","05.class-based-views/11.pagination",{"title":212,"path":213,"stem":214,"children":215},"Forms and User Input","/forms-and-user-input","06.forms-and-user-input/01.index",[216,217,221,225,229,233,237,241,245,249],{"title":212,"path":213,"stem":214},{"title":218,"path":219,"stem":220},"Understanding HTML Forms","/forms-and-user-input/understanding-html-forms","06.forms-and-user-input/02.understanding-html-forms",{"title":222,"path":223,"stem":224},"Django's Role in Form Handling","/forms-and-user-input/djangos-role-in-form-handling","06.forms-and-user-input/03.djangos-role-in-form-handling",{"title":226,"path":227,"stem":228},"Creating Forms with Forms API","/forms-and-user-input/creating-forms-with-forms-api","06.forms-and-user-input/04.creating-forms-with-forms-api",{"title":230,"path":231,"stem":232},"Form Validation","/forms-and-user-input/form-validation","06.forms-and-user-input/05.form-validation",{"title":234,"path":235,"stem":236},"Built-in Fields and Widgets","/forms-and-user-input/built-in-fields-and-widgets","06.forms-and-user-input/06.built-in-fields-and-widgets",{"title":238,"path":239,"stem":240},"Form Rendering in Templates","/forms-and-user-input/form-rendering-in-templates","06.forms-and-user-input/07.form-rendering-in-templates",{"title":242,"path":243,"stem":244},"Model Forms","/forms-and-user-input/model-forms","06.forms-and-user-input/08.model-forms",{"title":246,"path":247,"stem":248},"Advanced Form Techniques","/forms-and-user-input/advanced-form-techniques","06.forms-and-user-input/09.advanced-form-techniques",{"title":250,"path":251,"stem":252},"Security Considerations for Forms","/forms-and-user-input/security-considerations-for-forms","06.forms-and-user-input/10.security-considerations-for-forms",{"title":254,"path":255,"stem":256,"children":257},"Models and Databases","/models-and-databases","07.models-and-databases/01.index",[258,259,263,267,271,275,279,283,287,291,295,299,303,307,311,315,319,323,327],{"title":254,"path":255,"stem":256},{"title":260,"path":261,"stem":262},"Understanding Django Models","/models-and-databases/understanding-django-models","07.models-and-databases/02.understanding-django-models",{"title":264,"path":265,"stem":266},"Defining Fields","/models-and-databases/defining-fields","07.models-and-databases/03.defining-fields",{"title":268,"path":269,"stem":270},"Relationships and Foreign Keys","/models-and-databases/relationships-and-foreign-keys","07.models-and-databases/04.relationships-and-foreign-keys",{"title":272,"path":273,"stem":274},"Examples of Relationship Patterns","/models-and-databases/examples-of-relationship-patterns","07.models-and-databases/05.examples-of-relationship-patterns",{"title":276,"path":277,"stem":278},"Making Queries","/models-and-databases/making-queries","07.models-and-databases/06.making-queries",{"title":280,"path":281,"stem":282},"Filtering, Ordering, and Slicing","/models-and-databases/filtering-ordering-slicing","07.models-and-databases/07.filtering-ordering-slicing",{"title":284,"path":285,"stem":286},"Managers and QuerySets","/models-and-databases/managers-and-querysets","07.models-and-databases/08.managers-and-querysets",{"title":288,"path":289,"stem":290},"Aggregation","/models-and-databases/aggregation","07.models-and-databases/09.aggregation",{"title":292,"path":293,"stem":294},"Search","/models-and-databases/search","07.models-and-databases/10.search",{"title":296,"path":297,"stem":298},"Raw SQL Queries","/models-and-databases/raw-sql-queries","07.models-and-databases/11.raw-sql-queries",{"title":300,"path":301,"stem":302},"Transactions","/models-and-databases/transactions","07.models-and-databases/12.transactions",{"title":304,"path":305,"stem":306},"Multiple Databases","/models-and-databases/multiple-databases","07.models-and-databases/13.multiple-databases",{"title":308,"path":309,"stem":310},"Tablespaces","/models-and-databases/tablespaces","07.models-and-databases/14.tablespaces",{"title":312,"path":313,"stem":314},"Composite Primary Keys","/models-and-databases/composite-primary-keys","07.models-and-databases/15.composite-primary-keys",{"title":316,"path":317,"stem":318},"Database Instrumentation","/models-and-databases/database-instrumentation","07.models-and-databases/16.database-instrumentation",{"title":320,"path":321,"stem":322},"Database Optimization","/models-and-databases/database-optimization","07.models-and-databases/17.database-optimization",{"title":324,"path":325,"stem":326},"Fixtures","/models-and-databases/fixtures","07.models-and-databases/18.fixtures",{"title":328,"path":329,"stem":330},"Signals","/models-and-databases/signals","07.models-and-databases/19.signals",{"title":332,"path":333,"stem":334,"children":335},"Migrations","/migrations","08.migrations/01.index",[336,337,341,345,349,353,357,361,365,369,373,377,381,385],{"title":332,"path":333,"stem":334},{"title":338,"path":339,"stem":340},"How Migrations Work","/migrations/how-migrations-work","08.migrations/02.how-migrations-work",{"title":342,"path":343,"stem":344},"Management Commands","/migrations/management-commands","08.migrations/03.management-commands",{"title":346,"path":347,"stem":348},"Dependencies and Workflow","/migrations/dependencies-and-workflow","08.migrations/04.dependencies-and-workflow",{"title":350,"path":351,"stem":352},"Transaction Handling","/migrations/transaction-handling","08.migrations/05.transaction-handling",{"title":354,"path":355,"stem":356},"Adding Migrations to Apps","/migrations/adding-migrations-to-apps","08.migrations/06.adding-migrations-to-apps",{"title":358,"path":359,"stem":360},"Reversing Migrations","/migrations/reversing-migrations","08.migrations/07.reversing-migrations",{"title":362,"path":363,"stem":364},"Historical Models","/migrations/historical-models","08.migrations/08.historical-models",{"title":366,"path":367,"stem":368},"Considerations When Removing Fields","/migrations/considerations-when-removing-fields","08.migrations/09.considerations-when-removing-fields",{"title":370,"path":371,"stem":372},"Data Migrations","/migrations/data-migrations","08.migrations/10.data-migrations",{"title":374,"path":375,"stem":376},"Squashing Migrations","/migrations/squashing-migrations","08.migrations/11.squashing-migrations",{"title":378,"path":379,"stem":380},"Serializing Values","/migrations/serializing-values","08.migrations/12.serializing-values",{"title":382,"path":383,"stem":384},"Supporting Multiple Django Versions","/migrations/supporting-multiple-django-versions","08.migrations/13.supporting-multiple-django-versions",{"title":386,"path":387,"stem":388},"Django Serialization Framework","/migrations/django-serialization-framework","08.migrations/14.django-serialization-framework",{"title":390,"path":391,"stem":392,"children":393},"Authentication and Authorization","/authentication-and-authorization","09.authentication-and-authorization/01.index",[394,395,399,403,407,411,415,419,423,427,431,435],{"title":390,"path":391,"stem":392},{"title":396,"path":397,"stem":398},"Overview of Django's Authentication System","/authentication-and-authorization/overview-of-django-authentication-system","09.authentication-and-authorization/02.overview-of-django-authentication-system",{"title":400,"path":401,"stem":402},"Users and Groups","/authentication-and-authorization/users-and-groups","09.authentication-and-authorization/03.users-and-groups",{"title":404,"path":405,"stem":406},"Permissions","/authentication-and-authorization/permissions","09.authentication-and-authorization/04.permissions",{"title":408,"path":409,"stem":410},"Password Management","/authentication-and-authorization/password-management","09.authentication-and-authorization/05.password-management",{"title":412,"path":413,"stem":414},"Authentication Views","/authentication-and-authorization/authentication-views","09.authentication-and-authorization/06.authentication-views",{"title":416,"path":417,"stem":418},"Login and Logout","/authentication-and-authorization/login-and-logout","09.authentication-and-authorization/07.login-and-logout",{"title":420,"path":421,"stem":422},"Custom User Models","/authentication-and-authorization/custom-user-models","09.authentication-and-authorization/08.custom-user-models",{"title":424,"path":425,"stem":426},"Middleware for Authentication","/authentication-and-authorization/middleware-for-authentication","09.authentication-and-authorization/09.middleware-for-authentication",{"title":428,"path":429,"stem":430},"Authorization in Views and Templates","/authentication-and-authorization/authorization-in-views-and-templates","09.authentication-and-authorization/10.authorization-in-views-and-templates",{"title":432,"path":433,"stem":434},"Integrating Social Authentication","/authentication-and-authorization/integrating-social-authentication","09.authentication-and-authorization/11.integrating-social-authentication",{"title":436,"path":437,"stem":438},"Security Best Practices","/authentication-and-authorization/security-best-practices","09.authentication-and-authorization/12.security-best-practices",{"title":440,"path":441,"stem":442,"children":443},"Sessions, Cookies, and State","/sessions-cookies-state","10.sessions-cookies-state/01.index",[444,446,450,454,458],{"title":445,"path":441,"stem":442},"Sessions, Cookies, and State Management",{"title":447,"path":448,"stem":449},"Introduction to Sessions","/sessions-cookies-state/introduction-to-sessions","10.sessions-cookies-state/02.introduction-to-sessions",{"title":451,"path":452,"stem":453},"Working with Cookies","/sessions-cookies-state/working-with-cookies","10.sessions-cookies-state/03.working-with-cookies",{"title":455,"path":456,"stem":457},"Server-Side Session Storage Options","/sessions-cookies-state/server-side-session-storage-options","10.sessions-cookies-state/04.server-side-session-storage-options",{"title":459,"path":460,"stem":461},"Session Security","/sessions-cookies-state/session-security","10.sessions-cookies-state/05.session-security",{"title":463,"path":464,"stem":465,"children":466},"Working with Files","/working-with-files","11.working-with-files/01.index",[467,468,472,476,480,484],{"title":463,"path":464,"stem":465},{"title":469,"path":470,"stem":471},"Files in Models","/working-with-files/files-in-models","11.working-with-files/02.files-in-models",{"title":473,"path":474,"stem":475},"The File Object","/working-with-files/the-file-object","11.working-with-files/03.the-file-object",{"title":477,"path":478,"stem":479},"Storage Backends","/working-with-files/storage-backends","11.working-with-files/04.storage-backends",{"title":481,"path":482,"stem":483},"Using Cloud Storage Providers","/working-with-files/using-cloud-storage-providers","11.working-with-files/05.using-cloud-storage-providers",{"title":485,"path":486,"stem":487},"Managing Media in Production","/working-with-files/managing-media-in-production","11.working-with-files/06.managing-media-in-production",{"title":489,"path":490,"stem":491,"children":492},"Admin Site","/admin-site","12.admin-site/01.index",[493,494,498,502,506,510],{"title":489,"path":490,"stem":491},{"title":495,"path":496,"stem":497},"Enabling the Admin","/admin-site/enabling-the-admin","12.admin-site/02.enabling-the-admin",{"title":499,"path":500,"stem":501},"Registering Models","/admin-site/registering-models","12.admin-site/03.registering-models",{"title":503,"path":504,"stem":505},"Customizing Admin Display","/admin-site/customizing-admin-display","12.admin-site/04.customizing-admin-display",{"title":507,"path":508,"stem":509},"Admin Actions","/admin-site/admin-actions","12.admin-site/05.admin-actions",{"title":511,"path":512,"stem":513},"Admin Security Best Practices","/admin-site/admin-security-best-practices","12.admin-site/06.admin-security-best-practices",{"title":515,"path":516,"stem":517,"children":518},"Middleware","/middleware","13.middleware/01.index",[519,520,524,528,532,536],{"title":515,"path":516,"stem":517},{"title":521,"path":522,"stem":523},"Middleware Overview","/middleware/middleware-overview","13.middleware/02.middleware-overview",{"title":525,"path":526,"stem":527},"Built-in Middleware","/middleware/built-in-middleware","13.middleware/03.built-in-middleware",{"title":529,"path":530,"stem":531},"Creating Custom Middleware","/middleware/creating-custom-middleware","13.middleware/04.creating-custom-middleware",{"title":533,"path":534,"stem":535},"Middleware Ordering","/middleware/middleware-ordering","13.middleware/05.middleware-ordering",{"title":537,"path":538,"stem":539},"Performance and Debugging","/middleware/performance-and-debugging","13.middleware/06.performance-and-debugging",{"title":541,"path":542,"stem":543,"children":544},"Security","/security","14.security/01.index",[545,546,550,554,558,562,566,570,574],{"title":541,"path":542,"stem":543},{"title":547,"path":548,"stem":549},"Django Security Philosophy","/security/django-security-philosophy","14.security/02.django-security-philosophy",{"title":551,"path":552,"stem":553},"Cross Site Request Forgery","/security/cross-site-request-forgery","14.security/03.cross-site-request-forgery",{"title":555,"path":556,"stem":557},"Cross Site Scripting","/security/cross-site-scripting","14.security/04.cross-site-scripting",{"title":559,"path":560,"stem":561},"SQL Injection Protection","/security/sql-injection-protection","14.security/05.sql-injection-protection",{"title":563,"path":564,"stem":565},"Clickjacking Protection","/security/clickjacking-protection","14.security/06.clickjacking-protection",{"title":567,"path":568,"stem":569},"HTTPS Setup and HSTS","/security/https-setup-and-hsts","14.security/07.https-setup-and-hsts",{"title":571,"path":572,"stem":573},"Password Storage and Cryptography","/security/password-storage-and-cryptography","14.security/08.password-storage-and-cryptography",{"title":575,"path":576,"stem":577},"Secure Deployment Checklist","/security/secure-deployment-checklist","14.security/09.secure-deployment-checklist",{"title":579,"path":580,"stem":581,"children":582},"Testing","/testing","15.testing/01.index",[583,584,588,592,596,600,604,608,612,616,620],{"title":579,"path":580,"stem":581},{"title":585,"path":586,"stem":587},"Introduction to Django Testing","/testing/introduction-to-django-testing","15.testing/02.introduction-to-django-testing",{"title":589,"path":590,"stem":591},"Writing and Running Tests","/testing/writing-and-running-tests","15.testing/03.writing-and-running-tests",{"title":593,"path":594,"stem":595},"Test Tools","/testing/test-tools","15.testing/04.test-tools",{"title":597,"path":598,"stem":599},"Testing Models","/testing/testing-models","15.testing/05.testing-models",{"title":601,"path":602,"stem":603},"Testing Views","/testing/testing-views","15.testing/06.testing-views",{"title":605,"path":606,"stem":607},"Testing Forms","/testing/testing-forms","15.testing/07.testing-forms",{"title":609,"path":610,"stem":611},"Testing Templates","/testing/testing-templates","15.testing/08.testing-templates",{"title":613,"path":614,"stem":615},"Testing Authentication","/testing/testing-authentication","15.testing/09.testing-authentication",{"title":617,"path":618,"stem":619},"Advanced Testing Topics","/testing/advanced-testing-topics","15.testing/10.advanced-testing-topics",{"title":621,"path":622,"stem":623},"Performance Testing","/testing/performance-testing","15.testing/11.performance-testing",{"title":625,"path":626,"stem":627,"children":628},"Static Assets and Frontend Integration","/static-assets-and-frontend-integration","16.static-assets-and-frontend-integration/01.index",[629,630,634,638,642,646],{"title":625,"path":626,"stem":627},{"title":631,"path":632,"stem":633},"Working with Static Files","/static-assets-and-frontend-integration/working-with-static-files","16.static-assets-and-frontend-integration/02.working-with-static-files",{"title":635,"path":636,"stem":637},"Integrating CSS and JavaScript","/static-assets-and-frontend-integration/integrating-css-and-javascript","16.static-assets-and-frontend-integration/03.integrating-css-and-javascript",{"title":639,"path":640,"stem":641},"Using Build Tools like Vite or Webpack","/static-assets-and-frontend-integration/using-build-tools-like-vite-or-webpack","16.static-assets-and-frontend-integration/04.using-build-tools-like-vite-or-webpack",{"title":643,"path":644,"stem":645},"Using React or Vue with Django","/static-assets-and-frontend-integration/using-react-or-vue-with-django","16.static-assets-and-frontend-integration/05.using-react-or-vue-with-django",{"title":647,"path":648,"stem":649},"Managing CORS","/static-assets-and-frontend-integration/managing-cors","16.static-assets-and-frontend-integration/06.managing-cors",{"title":651,"path":652,"stem":653,"children":654},"Internationalization and Localization","/internationalization-and-localization","17.internationalization-and-localization/01.index",[655,656,660,664,668],{"title":651,"path":652,"stem":653},{"title":657,"path":658,"stem":659},"Enabling Translation","/internationalization-and-localization/enabling-translation","17.internationalization-and-localization/02.enabling-translation",{"title":661,"path":662,"stem":663},"Translating Text in Code and Templates","/internationalization-and-localization/translating-text-in-code-and-templates","17.internationalization-and-localization/03.translating-text-in-code-and-templates",{"title":665,"path":666,"stem":667},"Timezone Support","/internationalization-and-localization/timezone-support","17.internationalization-and-localization/04.timezone-support",{"title":669,"path":670,"stem":671},"Locale Middleware","/internationalization-and-localization/locale-middleware","17.internationalization-and-localization/05.locale-middleware",{"title":673,"path":674,"stem":675,"children":676},"Caching","/caching","18.caching/01.index",[677,678,682,686,690,694,698],{"title":673,"path":674,"stem":675},{"title":679,"path":680,"stem":681},"Introduction to Caching","/caching/introduction-to-caching","18.caching/02.introduction-to-caching",{"title":683,"path":684,"stem":685},"Cache Backends","/caching/cache-backends","18.caching/03.cache-backends",{"title":687,"path":688,"stem":689},"Per View Caching","/caching/per-view-caching","18.caching/04.per-view-caching",{"title":691,"path":692,"stem":693},"Low Level Cache API","/caching/low-level-cache-api","18.caching/05.low-level-cache-api",{"title":695,"path":696,"stem":697},"Template Fragment Caching","/caching/template-fragment-caching","18.caching/06.template-fragment-caching",{"title":699,"path":700,"stem":701},"Deployment Level Caching Patterns","/caching/deployment-level-caching-patterns","18.caching/07.deployment-level-caching-patterns",{"title":703,"path":704,"stem":705,"children":706},"Asynchronous Django","/asynchronous-django","19.asynchronous-django/01.index",[707,708,712,716,720,724,728,732],{"title":703,"path":704,"stem":705},{"title":709,"path":710,"stem":711},"Introduction to ASGI","/asynchronous-django/introduction-to-asgi","19.asynchronous-django/02.introduction-to-asgi",{"title":713,"path":714,"stem":715},"Async Views","/asynchronous-django/async-views","19.asynchronous-django/03.async-views",{"title":717,"path":718,"stem":719},"Async ORM Status","/asynchronous-django/async-orm-status","19.asynchronous-django/04.async-orm-status",{"title":721,"path":722,"stem":723},"WebSockets with Channels","/asynchronous-django/websockets-with-channels","19.asynchronous-django/05.websockets-with-channels",{"title":725,"path":726,"stem":727},"Background Tasks with Celery or RQ","/asynchronous-django/background-tasks-with-celery-or-rq","19.asynchronous-django/06.background-tasks-with-celery-or-rq",{"title":729,"path":730,"stem":731},"Asynchronous Support","/asynchronous-django/asynchronous-support","19.asynchronous-django/07.asynchronous-support",{"title":733,"path":734,"stem":735},"Django's Tasks Framework","/asynchronous-django/django-tasks-framework","19.asynchronous-django/08.django-tasks-framework",{"title":737,"path":738,"stem":739,"children":740},"Deployment","/deployment","20.deployment/01.index",[741,742,746,750,754,758,762,766,770],{"title":737,"path":738,"stem":739},{"title":743,"path":744,"stem":745},"Preparing for Production","/deployment/preparing-for-production","20.deployment/02.preparing-for-production",{"title":747,"path":748,"stem":749},"Using WSGI and ASGI Servers","/deployment/using-wsgi-and-asgi-servers","20.deployment/03.using-wsgi-and-asgi-servers",{"title":751,"path":752,"stem":753},"Deploying on Linux Servers","/deployment/deploying-on-linux-servers","20.deployment/04.deploying-on-linux-servers",{"title":755,"path":756,"stem":757},"Using Docker","/deployment/using-docker","20.deployment/05.using-docker",{"title":759,"path":760,"stem":761},"Cloud Deployment Guides","/deployment/cloud-deployment-guides","20.deployment/06.cloud-deployment-guides",{"title":763,"path":764,"stem":765},"Scaling and Load Balancing","/deployment/scaling-and-load-balancing","20.deployment/07.scaling-and-load-balancing",{"title":767,"path":768,"stem":769},"Monitoring and Logging","/deployment/monitoring-and-logging","20.deployment/08.monitoring-and-logging",{"title":771,"path":772,"stem":773},"Backup Strategies","/deployment/backup-strategies","20.deployment/09.backup-strategies",{"title":775,"path":776,"stem":777,"children":778},"Performance and Optimization","/performance-and-optimization","21.performance-and-optimization/01.index",[779,780,784,788,792,796],{"title":775,"path":776,"stem":777},{"title":781,"path":782,"stem":783},"Query Optimization","/performance-and-optimization/query-optimization","21.performance-and-optimization/02.query-optimization",{"title":785,"path":786,"stem":787},"Template Rendering Optimization","/performance-and-optimization/template-rendering-optimization","21.performance-and-optimization/03.template-rendering-optimization",{"title":789,"path":790,"stem":791},"Using Select Related and Prefetch Related","/performance-and-optimization/using-select-related-and-prefetch-related","21.performance-and-optimization/04.using-select-related-and-prefetch-related",{"title":793,"path":794,"stem":795},"Caching Strategies","/performance-and-optimization/caching-strategies","21.performance-and-optimization/05.caching-strategies",{"title":797,"path":798,"stem":799},"Profiling Django Apps","/performance-and-optimization/profiling-django-apps","21.performance-and-optimization/06.profiling-django-apps",{"title":801,"path":802,"stem":803,"children":804},"Advanced and Expert Topics","/advanced-and-expert-topics","22.advanced-and-expert-topics/01.index",[805,806,810,814,818,822,826,830,834,838,842,846],{"title":801,"path":802,"stem":803},{"title":807,"path":808,"stem":809},"System Architecture Patterns","/advanced-and-expert-topics/system-architecture-patterns","22.advanced-and-expert-topics/02.system-architecture-patterns",{"title":811,"path":812,"stem":813},"Domain Driven Design with Django","/advanced-and-expert-topics/domain-driven-design-with-django","22.advanced-and-expert-topics/03.domain-driven-design-with-django",{"title":815,"path":816,"stem":817},"Building Large Scale Django Projects","/advanced-and-expert-topics/building-large-scale-django-projects","22.advanced-and-expert-topics/04.building-large-scale-django-projects",{"title":819,"path":820,"stem":821},"Plugin Architectures for Django Apps","/advanced-and-expert-topics/plugin-architectures-for-django-apps","22.advanced-and-expert-topics/05.plugin-architectures-for-django-apps",{"title":823,"path":824,"stem":825},"Extending Django's Core","/advanced-and-expert-topics/extending-djangos-core","22.advanced-and-expert-topics/06.extending-djangos-core",{"title":827,"path":828,"stem":829},"Custom ORM Expressions","/advanced-and-expert-topics/custom-orm-expressions","22.advanced-and-expert-topics/07.custom-orm-expressions",{"title":831,"path":832,"stem":833},"Custom Management Commands","/advanced-and-expert-topics/custom-management-commands","22.advanced-and-expert-topics/08.custom-management-commands",{"title":835,"path":836,"stem":837},"Working with Signals","/advanced-and-expert-topics/working-with-signals","22.advanced-and-expert-topics/09.working-with-signals",{"title":839,"path":840,"stem":841},"Building Reusable Django Packages","/advanced-and-expert-topics/building-reusable-django-packages","22.advanced-and-expert-topics/10.building-reusable-django-packages",{"title":843,"path":844,"stem":845},"Integrating Microservices","/advanced-and-expert-topics/integrating-microservices","22.advanced-and-expert-topics/11.integrating-microservices",{"title":847,"path":848,"stem":849},"Advanced Security Hardening","/advanced-and-expert-topics/advanced-security-hardening","22.advanced-and-expert-topics/12.advanced-security-hardening",{"title":851,"path":852,"stem":853,"children":854},"Logging in Django","/logging-in-django","23.logging-in-django/01.index",[855],{"title":851,"path":852,"stem":853},{"title":857,"path":858,"stem":859,"children":860},"FAQ and Troubleshooting","/faq-and-troubleshooting","24.faq-and-troubleshooting/01.index",[861],{"title":857,"path":858,"stem":859},{"title":863,"path":864,"stem":865,"children":866},"External Packages and Ecosystem","/external-packages-and-ecosystem","25.external-packages-and-ecosystem/01.index",[867],{"title":863,"path":864,"stem":865},{"title":869,"path":870,"stem":871,"children":872},"Django Internals and Contributing","/django-internals-and-contributing","26.django-internals-and-contributing/01.index",[873],{"title":869,"path":870,"stem":871},{"title":875,"path":876,"stem":877,"children":878},"Microservices with Django","/microservices-with-django","27.microservices-with-django/01.index",[879,880,884,888,892,896,900,904,908,912,916,920,924],{"title":875,"path":876,"stem":877},{"title":881,"path":882,"stem":883},"What Is a Microservice?","/microservices-with-django/what-is-a-microservice","27.microservices-with-django/02.what-is-a-microservice",{"title":885,"path":886,"stem":887},"Introducing the Django Microservices Architecture","/microservices-with-django/django-microservices-architecture","27.microservices-with-django/03.django-microservices-architecture",{"title":889,"path":890,"stem":891},"Setting Up the Development and Runtime Environment","/microservices-with-django/development-environment","27.microservices-with-django/04.development-environment",{"title":893,"path":894,"stem":895},"Cloud-native Data Processing with MongoDB","/microservices-with-django/cloud-native-data-processing","27.microservices-with-django/05.cloud-native-data-processing",{"title":897,"path":898,"stem":899},"Creating RESTful APIs for Microservices","/microservices-with-django/restful-apis","27.microservices-with-django/06.restful-apis",{"title":901,"path":902,"stem":903},"Orchestrating Microservices with Celery and RabbitMQ","/microservices-with-django/orchestrating-celery-rabbitmq","27.microservices-with-django/07.orchestrating-celery-rabbitmq",{"title":905,"path":906,"stem":907},"Testing Microservices","/microservices-with-django/testing-microservices","27.microservices-with-django/08.testing-microservices",{"title":909,"path":910,"stem":911},"Deploying Microservices","/microservices-with-django/deploying-microservices","27.microservices-with-django/09.deploying-microservices",{"title":913,"path":914,"stem":915},"Securing Microservices","/microservices-with-django/securing-microservices","27.microservices-with-django/10.securing-microservices",{"title":917,"path":918,"stem":919},"Improving Microservices Performance with Caching","/microservices-with-django/performance-caching","27.microservices-with-django/11.performance-caching",{"title":921,"path":922,"stem":923},"Best Practices","/microservices-with-django/best-practices","27.microservices-with-django/12.best-practices",{"title":925,"path":926,"stem":927},"Transforming a Monolithic Web App into a Microservice version","/microservices-with-django/monolith-to-microservices","27.microservices-with-django/13.monolith-to-microservices",{"title":929,"path":930,"stem":931,"children":932},"Releases","/releases","releases",[933,936,940,944,948,952,956,960,964,968,972,976,980,984,988,992,996,1000,1004,1008,1012],{"title":934,"path":930,"stem":935},"Django Releases","releases/index",{"title":937,"path":938,"stem":939},"Django 5.1.10 release notes","/releases/5.1.10","releases/5.1.10",{"title":941,"path":942,"stem":943},"Django 5.1.11 release notes","/releases/5.1.11","releases/5.1.11",{"title":945,"path":946,"stem":947},"Django 5.1.12 release notes","/releases/5.1.12","releases/5.1.12",{"title":949,"path":950,"stem":951},"Django 5.1.13 release notes","/releases/5.1.13","releases/5.1.13",{"title":953,"path":954,"stem":955},"Django 5.1.14 release notes","/releases/5.1.14","releases/5.1.14",{"title":957,"path":958,"stem":959},"Django 5.1.15 release notes","/releases/5.1.15","releases/5.1.15",{"title":961,"path":962,"stem":963},"Django 5.2 release notes","/releases/5.2","releases/5.2",{"title":965,"path":966,"stem":967},"Django 5.2.1 release notes","/releases/5.2.1","releases/5.2.1",{"title":969,"path":970,"stem":971},"Django 5.2.10 release notes","/releases/5.2.10","releases/5.2.10",{"title":973,"path":974,"stem":975},"Django 5.2.2 release notes","/releases/5.2.2","releases/5.2.2",{"title":977,"path":978,"stem":979},"Django 5.2.3 release notes","/releases/5.2.3","releases/5.2.3",{"title":981,"path":982,"stem":983},"Django 5.2.4 release notes","/releases/5.2.4","releases/5.2.4",{"title":985,"path":986,"stem":987},"Django 5.2.5 release notes","/releases/5.2.5","releases/5.2.5",{"title":989,"path":990,"stem":991},"Django 5.2.6 release notes","/releases/5.2.6","releases/5.2.6",{"title":993,"path":994,"stem":995},"Django 5.2.7 release notes","/releases/5.2.7","releases/5.2.7",{"title":997,"path":998,"stem":999},"Django 5.2.8 release notes","/releases/5.2.8","releases/5.2.8",{"title":1001,"path":1002,"stem":1003},"Django 5.2.9 release notes","/releases/5.2.9","releases/5.2.9",{"title":1005,"path":1006,"stem":1007},"Django 6.0 release notes","/releases/6.0","releases/6.0",{"title":1009,"path":1010,"stem":1011},"Django 6.0.1 release notes","/releases/6.0.1","releases/6.0.1",{"title":1013,"path":1014,"stem":1015},"Django 6.1 release notes - UNDER DEVELOPMENT","/releases/6.1","releases/6.1",{"id":1017,"title":579,"body":1018,"description":1028,"extension":2222,"links":2223,"meta":2224,"navigation":1335,"path":580,"seo":2225,"stem":581,"__hash__":2226},"docs/15.testing/01.index.md",{"type":1019,"value":1020,"toc":2210},"minimark",[1021,1025,1029,1034,1037,1044,1050,1056,1062,1068,1072,1075,1081,1087,1093,1099,1103,1106,1112,1118,1124,1130,1134,1137,1143,1149,1155,1161,1167,1171,1174,1213,1217,1220,1253,1257,1260,1680,1683,1784,1788,1791,2158,2162,2165,2196,2200,2203,2206],[1022,1023,579],"h1",{"id":1024},"testing",[1026,1027,1028],"p",{},"Testing is a critical aspect of Django development that ensures your application works correctly, maintains quality over time, and provides confidence when making changes. Django provides a comprehensive testing framework built on Python's unittest module, along with additional tools specifically designed for web application testing.",[1030,1031,1033],"h2",{"id":1032},"why-testing-matters","Why Testing Matters",[1026,1035,1036],{},"Testing in Django applications serves multiple purposes:",[1026,1038,1039,1043],{},[1040,1041,1042],"strong",{},"Quality Assurance",": Tests verify that your code behaves as expected under various conditions, catching bugs before they reach production.",[1026,1045,1046,1049],{},[1040,1047,1048],{},"Regression Prevention",": Automated tests prevent previously fixed bugs from reappearing when you make changes to your codebase.",[1026,1051,1052,1055],{},[1040,1053,1054],{},"Documentation",": Well-written tests serve as living documentation, showing how your code is intended to be used.",[1026,1057,1058,1061],{},[1040,1059,1060],{},"Refactoring Confidence",": A comprehensive test suite allows you to refactor code with confidence, knowing that tests will catch any breaking changes.",[1026,1063,1064,1067],{},[1040,1065,1066],{},"Collaboration",": Tests help team members understand expected behavior and provide a safety net when multiple developers work on the same codebase.",[1030,1069,1071],{"id":1070},"djangos-testing-philosophy","Django's Testing Philosophy",[1026,1073,1074],{},"Django follows several key principles in its approach to testing:",[1026,1076,1077,1080],{},[1040,1078,1079],{},"Test-Driven Development (TDD)",": Django encourages writing tests before implementing features, helping you think through requirements and design better APIs.",[1026,1082,1083,1086],{},[1040,1084,1085],{},"Comprehensive Coverage",": Django's testing tools support testing all layers of your application, from models and views to forms and templates.",[1026,1088,1089,1092],{},[1040,1090,1091],{},"Isolation",": Each test should be independent and not rely on the state left by other tests, ensuring reliable and repeatable results.",[1026,1094,1095,1098],{},[1040,1096,1097],{},"Speed",": Django provides tools to make tests run quickly, including in-memory databases and efficient test data creation.",[1030,1100,1102],{"id":1101},"types-of-testing-in-django","Types of Testing in Django",[1026,1104,1105],{},"Django applications typically use several types of tests:",[1026,1107,1108,1111],{},[1040,1109,1110],{},"Unit Tests",": Test individual components (models, forms, utilities) in isolation to verify they work correctly on their own.",[1026,1113,1114,1117],{},[1040,1115,1116],{},"Integration Tests",": Test how different components work together, such as how views interact with models and templates.",[1026,1119,1120,1123],{},[1040,1121,1122],{},"Functional Tests",": Test complete user workflows from the browser's perspective, often using tools like Selenium.",[1026,1125,1126,1129],{},[1040,1127,1128],{},"Performance Tests",": Measure and verify that your application meets performance requirements under various loads.",[1030,1131,1133],{"id":1132},"testing-tools-and-frameworks","Testing Tools and Frameworks",[1026,1135,1136],{},"Django provides a rich ecosystem of testing tools:",[1026,1138,1139,1142],{},[1040,1140,1141],{},"Built-in Test Framework",": Django's TestCase classes provide database fixtures, URL routing, and template rendering for comprehensive testing.",[1026,1144,1145,1148],{},[1040,1146,1147],{},"Test Client",": A Python class that simulates a web browser, allowing you to test views and user interactions without running a web server.",[1026,1150,1151,1154],{},[1040,1152,1153],{},"Fixtures and Factories",": Tools for creating test data consistently and efficiently across your test suite.",[1026,1156,1157,1160],{},[1040,1158,1159],{},"Mocking and Patching",": Utilities for isolating code under test by replacing dependencies with controlled mock objects.",[1026,1162,1163,1166],{},[1040,1164,1165],{},"Coverage Analysis",": Tools to measure how much of your code is covered by tests and identify untested areas.",[1030,1168,1170],{"id":1169},"what-youll-learn","What You'll Learn",[1026,1172,1173],{},"This comprehensive testing guide covers:",[1175,1176,1177,1184,1190,1196,1202,1208],"ul",{},[1178,1179,1180,1183],"li",{},[1040,1181,1182],{},"Testing Fundamentals",": Understanding Django's testing framework and writing your first tests",[1178,1185,1186,1189],{},[1040,1187,1188],{},"Test Organization",": Structuring tests for maintainability and clarity",[1178,1191,1192,1195],{},[1040,1193,1194],{},"Component Testing",": Testing models, views, forms, and templates effectively",[1178,1197,1198,1201],{},[1040,1199,1200],{},"Authentication Testing",": Verifying user authentication and authorization logic",[1178,1203,1204,1207],{},[1040,1205,1206],{},"Advanced Techniques",": Mocking, fixtures, custom test runners, and performance testing",[1178,1209,1210,1212],{},[1040,1211,921],{},": Writing maintainable, fast, and reliable tests",[1030,1214,1216],{"id":1215},"testing-workflow","Testing Workflow",[1026,1218,1219],{},"A typical Django testing workflow includes:",[1221,1222,1223,1229,1235,1241,1247],"ol",{},[1178,1224,1225,1228],{},[1040,1226,1227],{},"Write Tests First",": Define expected behavior through tests before implementing features",[1178,1230,1231,1234],{},[1040,1232,1233],{},"Run Tests Frequently",": Execute tests during development to catch issues early",[1178,1236,1237,1240],{},[1040,1238,1239],{},"Maintain Test Coverage",": Ensure new code includes appropriate tests",[1178,1242,1243,1246],{},[1040,1244,1245],{},"Refactor with Confidence",": Use tests to verify that refactoring doesn't break functionality",[1178,1248,1249,1252],{},[1040,1250,1251],{},"Continuous Integration",": Automate test execution in your deployment pipeline",[1030,1254,1256],{"id":1255},"getting-started","Getting Started",[1026,1258,1259],{},"Django makes it easy to start testing:",[1261,1262,1267],"pre",{"className":1263,"code":1264,"language":1265,"meta":1266,"style":1266},"language-python shiki shiki-themes material-theme-lighter vitesse-light vitesse-dark","# tests.py\nfrom django.test import TestCase\nfrom django.contrib.auth.models import User\n\nclass UserTestCase(TestCase):\n    def setUp(self):\n        \"\"\"Set up test data\"\"\"\n        self.user = User.objects.create_user(\n            username='testuser',\n            email='test@example.com',\n            password='testpass123'\n        )\n    \n    def test_user_creation(self):\n        \"\"\"Test that user was created correctly\"\"\"\n        self.assertEqual(self.user.username, 'testuser')\n        self.assertEqual(self.user.email, 'test@example.com')\n        self.assertTrue(self.user.check_password('testpass123'))\n    \n    def test_user_str_representation(self):\n        \"\"\"Test user string representation\"\"\"\n        self.assertEqual(str(self.user), 'testuser')\n","python","",[1268,1269,1270,1279,1303,1330,1337,1358,1376,1390,1423,1446,1463,1479,1485,1491,1505,1515,1551,1583,1617,1622,1636,1646],"code",{"__ignoreMap":1266},[1271,1272,1275],"span",{"class":1273,"line":1274},"line",1,[1271,1276,1278],{"class":1277},"s9Tkl","# tests.py\n",[1271,1280,1282,1286,1290,1294,1297,1300],{"class":1273,"line":1281},2,[1271,1283,1285],{"class":1284},"siDh9","from",[1271,1287,1289],{"class":1288},"sftqT"," django",[1271,1291,1293],{"class":1292},"soVBu",".",[1271,1295,1296],{"class":1288},"test ",[1271,1298,1299],{"class":1284},"import",[1271,1301,1302],{"class":1288}," TestCase\n",[1271,1304,1306,1308,1310,1312,1315,1317,1320,1322,1325,1327],{"class":1273,"line":1305},3,[1271,1307,1285],{"class":1284},[1271,1309,1289],{"class":1288},[1271,1311,1293],{"class":1292},[1271,1313,1314],{"class":1288},"contrib",[1271,1316,1293],{"class":1292},[1271,1318,1319],{"class":1288},"auth",[1271,1321,1293],{"class":1292},[1271,1323,1324],{"class":1288},"models ",[1271,1326,1299],{"class":1284},[1271,1328,1329],{"class":1288}," User\n",[1271,1331,1333],{"class":1273,"line":1332},4,[1271,1334,1336],{"emptyLinePlaceholder":1335},true,"\n",[1271,1338,1340,1344,1348,1351,1355],{"class":1273,"line":1339},5,[1271,1341,1343],{"class":1342},"s5Kfy","class",[1271,1345,1347],{"class":1346},"sD-vU"," UserTestCase",[1271,1349,1350],{"class":1292},"(",[1271,1352,1354],{"class":1353},"sYn-s","TestCase",[1271,1356,1357],{"class":1292},"):\n",[1271,1359,1361,1364,1368,1370,1374],{"class":1273,"line":1360},6,[1271,1362,1363],{"class":1342},"    def",[1271,1365,1367],{"class":1366},"sljsM"," setUp",[1271,1369,1350],{"class":1292},[1271,1371,1373],{"class":1372},"sRjD_","self",[1271,1375,1357],{"class":1292},[1271,1377,1379,1383,1387],{"class":1273,"line":1378},7,[1271,1380,1382],{"class":1381},"sm7ve","        \"\"\"",[1271,1384,1386],{"class":1385},"sVyVU","Set up test data",[1271,1388,1389],{"class":1381},"\"\"\"\n",[1271,1391,1393,1397,1399,1403,1406,1409,1411,1414,1416,1420],{"class":1273,"line":1392},8,[1271,1394,1396],{"class":1395},"se3Ec","        self",[1271,1398,1293],{"class":1292},[1271,1400,1402],{"class":1401},"sBPpx","user",[1271,1404,1405],{"class":1292}," =",[1271,1407,1408],{"class":1288}," User",[1271,1410,1293],{"class":1292},[1271,1412,1413],{"class":1401},"objects",[1271,1415,1293],{"class":1292},[1271,1417,1419],{"class":1418},"siWMO","create_user",[1271,1421,1422],{"class":1292},"(\n",[1271,1424,1426,1430,1433,1437,1441,1443],{"class":1273,"line":1425},9,[1271,1427,1429],{"class":1428},"sqOPj","            username",[1271,1431,1432],{"class":1292},"=",[1271,1434,1436],{"class":1435},"sbYkP","'",[1271,1438,1440],{"class":1439},"sTbE_","testuser",[1271,1442,1436],{"class":1435},[1271,1444,1445],{"class":1292},",\n",[1271,1447,1449,1452,1454,1456,1459,1461],{"class":1273,"line":1448},10,[1271,1450,1451],{"class":1428},"            email",[1271,1453,1432],{"class":1292},[1271,1455,1436],{"class":1435},[1271,1457,1458],{"class":1439},"test@example.com",[1271,1460,1436],{"class":1435},[1271,1462,1445],{"class":1292},[1271,1464,1466,1469,1471,1473,1476],{"class":1273,"line":1465},11,[1271,1467,1468],{"class":1428},"            password",[1271,1470,1432],{"class":1292},[1271,1472,1436],{"class":1435},[1271,1474,1475],{"class":1439},"testpass123",[1271,1477,1478],{"class":1435},"'\n",[1271,1480,1482],{"class":1273,"line":1481},12,[1271,1483,1484],{"class":1292},"        )\n",[1271,1486,1488],{"class":1273,"line":1487},13,[1271,1489,1490],{"class":1288},"    \n",[1271,1492,1494,1496,1499,1501,1503],{"class":1273,"line":1493},14,[1271,1495,1363],{"class":1342},[1271,1497,1498],{"class":1366}," test_user_creation",[1271,1500,1350],{"class":1292},[1271,1502,1373],{"class":1372},[1271,1504,1357],{"class":1292},[1271,1506,1508,1510,1513],{"class":1273,"line":1507},15,[1271,1509,1382],{"class":1381},[1271,1511,1512],{"class":1385},"Test that user was created correctly",[1271,1514,1389],{"class":1381},[1271,1516,1518,1520,1522,1525,1527,1529,1531,1533,1535,1538,1541,1544,1546,1548],{"class":1273,"line":1517},16,[1271,1519,1396],{"class":1395},[1271,1521,1293],{"class":1292},[1271,1523,1524],{"class":1418},"assertEqual",[1271,1526,1350],{"class":1292},[1271,1528,1373],{"class":1395},[1271,1530,1293],{"class":1292},[1271,1532,1402],{"class":1401},[1271,1534,1293],{"class":1292},[1271,1536,1537],{"class":1401},"username",[1271,1539,1540],{"class":1292},",",[1271,1542,1543],{"class":1435}," '",[1271,1545,1440],{"class":1439},[1271,1547,1436],{"class":1435},[1271,1549,1550],{"class":1292},")\n",[1271,1552,1554,1556,1558,1560,1562,1564,1566,1568,1570,1573,1575,1577,1579,1581],{"class":1273,"line":1553},17,[1271,1555,1396],{"class":1395},[1271,1557,1293],{"class":1292},[1271,1559,1524],{"class":1418},[1271,1561,1350],{"class":1292},[1271,1563,1373],{"class":1395},[1271,1565,1293],{"class":1292},[1271,1567,1402],{"class":1401},[1271,1569,1293],{"class":1292},[1271,1571,1572],{"class":1401},"email",[1271,1574,1540],{"class":1292},[1271,1576,1543],{"class":1435},[1271,1578,1458],{"class":1439},[1271,1580,1436],{"class":1435},[1271,1582,1550],{"class":1292},[1271,1584,1586,1588,1590,1593,1595,1597,1599,1601,1603,1606,1608,1610,1612,1614],{"class":1273,"line":1585},18,[1271,1587,1396],{"class":1395},[1271,1589,1293],{"class":1292},[1271,1591,1592],{"class":1418},"assertTrue",[1271,1594,1350],{"class":1292},[1271,1596,1373],{"class":1395},[1271,1598,1293],{"class":1292},[1271,1600,1402],{"class":1401},[1271,1602,1293],{"class":1292},[1271,1604,1605],{"class":1418},"check_password",[1271,1607,1350],{"class":1292},[1271,1609,1436],{"class":1435},[1271,1611,1475],{"class":1439},[1271,1613,1436],{"class":1435},[1271,1615,1616],{"class":1292},"))\n",[1271,1618,1620],{"class":1273,"line":1619},19,[1271,1621,1490],{"class":1288},[1271,1623,1625,1627,1630,1632,1634],{"class":1273,"line":1624},20,[1271,1626,1363],{"class":1342},[1271,1628,1629],{"class":1366}," test_user_str_representation",[1271,1631,1350],{"class":1292},[1271,1633,1373],{"class":1372},[1271,1635,1357],{"class":1292},[1271,1637,1639,1641,1644],{"class":1273,"line":1638},21,[1271,1640,1382],{"class":1381},[1271,1642,1643],{"class":1385},"Test user string representation",[1271,1645,1389],{"class":1381},[1271,1647,1649,1651,1653,1655,1657,1661,1663,1665,1667,1669,1672,1674,1676,1678],{"class":1273,"line":1648},22,[1271,1650,1396],{"class":1395},[1271,1652,1293],{"class":1292},[1271,1654,1524],{"class":1418},[1271,1656,1350],{"class":1292},[1271,1658,1660],{"class":1659},"sa2tF","str",[1271,1662,1350],{"class":1292},[1271,1664,1373],{"class":1395},[1271,1666,1293],{"class":1292},[1271,1668,1402],{"class":1401},[1271,1670,1671],{"class":1292},"),",[1271,1673,1543],{"class":1435},[1271,1675,1440],{"class":1439},[1271,1677,1436],{"class":1435},[1271,1679,1550],{"class":1292},[1026,1681,1682],{},"Run tests with Django's management command:",[1261,1684,1688],{"className":1685,"code":1686,"language":1687,"meta":1266,"style":1266},"language-bash shiki shiki-themes material-theme-lighter vitesse-light vitesse-dark","# Run all tests\npython manage.py test\n\n# Run specific test module\npython manage.py test myapp.tests\n\n# Run with verbose output\npython manage.py test --verbosity=2\n\n# Run with coverage\ncoverage run --source='.' manage.py test\ncoverage report\n","bash",[1268,1689,1690,1695,1705,1709,1714,1726,1730,1735,1747,1751,1756,1777],{"__ignoreMap":1266},[1271,1691,1692],{"class":1273,"line":1274},[1271,1693,1694],{"class":1277},"# Run all tests\n",[1271,1696,1697,1699,1702],{"class":1273,"line":1281},[1271,1698,1265],{"class":1353},[1271,1700,1701],{"class":1439}," manage.py",[1271,1703,1704],{"class":1439}," test\n",[1271,1706,1707],{"class":1273,"line":1305},[1271,1708,1336],{"emptyLinePlaceholder":1335},[1271,1710,1711],{"class":1273,"line":1332},[1271,1712,1713],{"class":1277},"# Run specific test module\n",[1271,1715,1716,1718,1720,1723],{"class":1273,"line":1339},[1271,1717,1265],{"class":1353},[1271,1719,1701],{"class":1439},[1271,1721,1722],{"class":1439}," test",[1271,1724,1725],{"class":1439}," myapp.tests\n",[1271,1727,1728],{"class":1273,"line":1360},[1271,1729,1336],{"emptyLinePlaceholder":1335},[1271,1731,1732],{"class":1273,"line":1378},[1271,1733,1734],{"class":1277},"# Run with verbose output\n",[1271,1736,1737,1739,1741,1743],{"class":1273,"line":1392},[1271,1738,1265],{"class":1353},[1271,1740,1701],{"class":1439},[1271,1742,1722],{"class":1439},[1271,1744,1746],{"class":1745},"sz9Cv"," --verbosity=2\n",[1271,1748,1749],{"class":1273,"line":1425},[1271,1750,1336],{"emptyLinePlaceholder":1335},[1271,1752,1753],{"class":1273,"line":1448},[1271,1754,1755],{"class":1277},"# Run with coverage\n",[1271,1757,1758,1761,1764,1767,1769,1771,1773,1775],{"class":1273,"line":1465},[1271,1759,1760],{"class":1353},"coverage",[1271,1762,1763],{"class":1439}," run",[1271,1765,1766],{"class":1745}," --source=",[1271,1768,1436],{"class":1435},[1271,1770,1293],{"class":1439},[1271,1772,1436],{"class":1435},[1271,1774,1701],{"class":1439},[1271,1776,1704],{"class":1439},[1271,1778,1779,1781],{"class":1273,"line":1481},[1271,1780,1760],{"class":1353},[1271,1782,1783],{"class":1439}," report\n",[1030,1785,1787],{"id":1786},"test-driven-development-example","Test-Driven Development Example",[1026,1789,1790],{},"Here's a simple TDD workflow:",[1261,1792,1794],{"className":1263,"code":1793,"language":1265,"meta":1266,"style":1266},"# 1. Write a failing test\nclass BlogPostTestCase(TestCase):\n    def test_post_slug_generation(self):\n        \"\"\"Test that post slug is generated from title\"\"\"\n        post = BlogPost.objects.create(\n            title=\"My First Blog Post\",\n            content=\"This is the content.\"\n        )\n        self.assertEqual(post.slug, \"my-first-blog-post\")\n\n# 2. Run test (it fails because BlogPost doesn't exist)\n# python manage.py test\n\n# 3. Write minimal code to make test pass\nclass BlogPost(models.Model):\n    title = models.CharField(max_length=200)\n    content = models.TextField()\n    slug = models.SlugField(unique=True)\n    \n    def save(self, *args, **kwargs):\n        if not self.slug:\n            self.slug = slugify(self.title)\n        super().save(*args, **kwargs)\n\n# 4. Run test again (it passes)\n# 5. Refactor if needed, keeping tests green\n",[1268,1795,1796,1801,1814,1827,1836,1857,1874,1889,1893,1923,1927,1932,1937,1941,1946,1964,1992,2009,2036,2040,2071,2089,2114,2141,2146,2152],{"__ignoreMap":1266},[1271,1797,1798],{"class":1273,"line":1274},[1271,1799,1800],{"class":1277},"# 1. Write a failing test\n",[1271,1802,1803,1805,1808,1810,1812],{"class":1273,"line":1281},[1271,1804,1343],{"class":1342},[1271,1806,1807],{"class":1346}," BlogPostTestCase",[1271,1809,1350],{"class":1292},[1271,1811,1354],{"class":1353},[1271,1813,1357],{"class":1292},[1271,1815,1816,1818,1821,1823,1825],{"class":1273,"line":1305},[1271,1817,1363],{"class":1342},[1271,1819,1820],{"class":1366}," test_post_slug_generation",[1271,1822,1350],{"class":1292},[1271,1824,1373],{"class":1372},[1271,1826,1357],{"class":1292},[1271,1828,1829,1831,1834],{"class":1273,"line":1332},[1271,1830,1382],{"class":1381},[1271,1832,1833],{"class":1385},"Test that post slug is generated from title",[1271,1835,1389],{"class":1381},[1271,1837,1838,1841,1843,1846,1848,1850,1852,1855],{"class":1273,"line":1339},[1271,1839,1840],{"class":1288},"        post ",[1271,1842,1432],{"class":1292},[1271,1844,1845],{"class":1288}," BlogPost",[1271,1847,1293],{"class":1292},[1271,1849,1413],{"class":1401},[1271,1851,1293],{"class":1292},[1271,1853,1854],{"class":1418},"create",[1271,1856,1422],{"class":1292},[1271,1858,1859,1862,1864,1867,1870,1872],{"class":1273,"line":1360},[1271,1860,1861],{"class":1428},"            title",[1271,1863,1432],{"class":1292},[1271,1865,1866],{"class":1435},"\"",[1271,1868,1869],{"class":1439},"My First Blog Post",[1271,1871,1866],{"class":1435},[1271,1873,1445],{"class":1292},[1271,1875,1876,1879,1881,1883,1886],{"class":1273,"line":1378},[1271,1877,1878],{"class":1428},"            content",[1271,1880,1432],{"class":1292},[1271,1882,1866],{"class":1435},[1271,1884,1885],{"class":1439},"This is the content.",[1271,1887,1888],{"class":1435},"\"\n",[1271,1890,1891],{"class":1273,"line":1392},[1271,1892,1484],{"class":1292},[1271,1894,1895,1897,1899,1901,1903,1906,1908,1911,1913,1916,1919,1921],{"class":1273,"line":1425},[1271,1896,1396],{"class":1395},[1271,1898,1293],{"class":1292},[1271,1900,1524],{"class":1418},[1271,1902,1350],{"class":1292},[1271,1904,1905],{"class":1418},"post",[1271,1907,1293],{"class":1292},[1271,1909,1910],{"class":1401},"slug",[1271,1912,1540],{"class":1292},[1271,1914,1915],{"class":1435}," \"",[1271,1917,1918],{"class":1439},"my-first-blog-post",[1271,1920,1866],{"class":1435},[1271,1922,1550],{"class":1292},[1271,1924,1925],{"class":1273,"line":1448},[1271,1926,1336],{"emptyLinePlaceholder":1335},[1271,1928,1929],{"class":1273,"line":1465},[1271,1930,1931],{"class":1277},"# 2. Run test (it fails because BlogPost doesn't exist)\n",[1271,1933,1934],{"class":1273,"line":1481},[1271,1935,1936],{"class":1277},"# python manage.py test\n",[1271,1938,1939],{"class":1273,"line":1487},[1271,1940,1336],{"emptyLinePlaceholder":1335},[1271,1942,1943],{"class":1273,"line":1493},[1271,1944,1945],{"class":1277},"# 3. Write minimal code to make test pass\n",[1271,1947,1948,1950,1952,1954,1957,1959,1962],{"class":1273,"line":1507},[1271,1949,1343],{"class":1342},[1271,1951,1845],{"class":1346},[1271,1953,1350],{"class":1292},[1271,1955,1956],{"class":1353},"models",[1271,1958,1293],{"class":1292},[1271,1960,1961],{"class":1353},"Model",[1271,1963,1357],{"class":1292},[1271,1965,1966,1969,1971,1974,1976,1979,1981,1984,1986,1990],{"class":1273,"line":1517},[1271,1967,1968],{"class":1288},"    title ",[1271,1970,1432],{"class":1292},[1271,1972,1973],{"class":1288}," models",[1271,1975,1293],{"class":1292},[1271,1977,1978],{"class":1418},"CharField",[1271,1980,1350],{"class":1292},[1271,1982,1983],{"class":1428},"max_length",[1271,1985,1432],{"class":1292},[1271,1987,1989],{"class":1988},"s7CZa","200",[1271,1991,1550],{"class":1292},[1271,1993,1994,1997,1999,2001,2003,2006],{"class":1273,"line":1553},[1271,1995,1996],{"class":1288},"    content ",[1271,1998,1432],{"class":1292},[1271,2000,1973],{"class":1288},[1271,2002,1293],{"class":1292},[1271,2004,2005],{"class":1418},"TextField",[1271,2007,2008],{"class":1292},"()\n",[1271,2010,2011,2014,2016,2018,2020,2023,2025,2028,2030,2034],{"class":1273,"line":1585},[1271,2012,2013],{"class":1288},"    slug ",[1271,2015,1432],{"class":1292},[1271,2017,1973],{"class":1288},[1271,2019,1293],{"class":1292},[1271,2021,2022],{"class":1418},"SlugField",[1271,2024,1350],{"class":1292},[1271,2026,2027],{"class":1428},"unique",[1271,2029,1432],{"class":1292},[1271,2031,2033],{"class":2032},"s8XtY","True",[1271,2035,1550],{"class":1292},[1271,2037,2038],{"class":1273,"line":1619},[1271,2039,1490],{"class":1288},[1271,2041,2042,2044,2047,2049,2051,2053,2057,2061,2063,2066,2069],{"class":1273,"line":1624},[1271,2043,1363],{"class":1342},[1271,2045,2046],{"class":1366}," save",[1271,2048,1350],{"class":1292},[1271,2050,1373],{"class":1372},[1271,2052,1540],{"class":1292},[1271,2054,2056],{"class":2055},"sVsLi"," *",[1271,2058,2060],{"class":2059},"sCyAa","args",[1271,2062,1540],{"class":1292},[1271,2064,2065],{"class":2055}," **",[1271,2067,2068],{"class":2059},"kwargs",[1271,2070,1357],{"class":1292},[1271,2072,2073,2076,2079,2082,2084,2086],{"class":1273,"line":1638},[1271,2074,2075],{"class":1284},"        if",[1271,2077,2078],{"class":2055}," not",[1271,2080,2081],{"class":1395}," self",[1271,2083,1293],{"class":1292},[1271,2085,1910],{"class":1401},[1271,2087,2088],{"class":1292},":\n",[1271,2090,2091,2094,2096,2098,2100,2103,2105,2107,2109,2112],{"class":1273,"line":1648},[1271,2092,2093],{"class":1395},"            self",[1271,2095,1293],{"class":1292},[1271,2097,1910],{"class":1401},[1271,2099,1405],{"class":1292},[1271,2101,2102],{"class":1418}," slugify",[1271,2104,1350],{"class":1292},[1271,2106,1373],{"class":1395},[1271,2108,1293],{"class":1292},[1271,2110,2111],{"class":1401},"title",[1271,2113,1550],{"class":1292},[1271,2115,2117,2120,2123,2126,2128,2131,2133,2135,2137,2139],{"class":1273,"line":2116},23,[1271,2118,2119],{"class":1659},"        super",[1271,2121,2122],{"class":1292},"().",[1271,2124,2125],{"class":1418},"save",[1271,2127,1350],{"class":1292},[1271,2129,2130],{"class":2055},"*",[1271,2132,2060],{"class":1418},[1271,2134,1540],{"class":1292},[1271,2136,2065],{"class":2055},[1271,2138,2068],{"class":1418},[1271,2140,1550],{"class":1292},[1271,2142,2144],{"class":1273,"line":2143},24,[1271,2145,1336],{"emptyLinePlaceholder":1335},[1271,2147,2149],{"class":1273,"line":2148},25,[1271,2150,2151],{"class":1277},"# 4. Run test again (it passes)\n",[1271,2153,2155],{"class":1273,"line":2154},26,[1271,2156,2157],{"class":1277},"# 5. Refactor if needed, keeping tests green\n",[1030,2159,2161],{"id":2160},"benefits-of-comprehensive-testing","Benefits of Comprehensive Testing",[1026,2163,2164],{},"Well-tested Django applications provide:",[1175,2166,2167,2173,2179,2184,2190],{},[1178,2168,2169,2172],{},[1040,2170,2171],{},"Reliability",": Confidence that your application works as intended",[1178,2174,2175,2178],{},[1040,2176,2177],{},"Maintainability",": Easier to modify and extend code without breaking existing functionality",[1178,2180,2181,2183],{},[1040,2182,1054],{},": Tests serve as examples of how to use your code",[1178,2185,2186,2189],{},[1040,2187,2188],{},"Team Collaboration",": Shared understanding of expected behavior",[1178,2191,2192,2195],{},[1040,2193,2194],{},"Deployment Confidence",": Assurance that changes won't break production",[1030,2197,2199],{"id":2198},"next-steps","Next Steps",[1026,2201,2202],{},"Ready to dive into Django testing? Start with the Introduction to Django Testing to understand the framework's testing capabilities, then progress through writing and running tests, exploring test tools, and testing specific components like models, views, and forms.",[1026,2204,2205],{},"Each chapter builds on the previous ones, providing practical examples and best practices that you can apply immediately to your Django projects. By the end of this guide, you'll have the knowledge and tools to implement comprehensive testing strategies that improve your application's quality and your confidence as a developer.",[2207,2208,2209],"style",{},"html pre.shiki code .s9Tkl, html code.shiki .s9Tkl{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#A0ADA0;--shiki-default-font-style:inherit;--shiki-dark:#758575DD;--shiki-dark-font-style:inherit}html pre.shiki code .siDh9, html code.shiki .siDh9{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#1E754F;--shiki-default-font-style:inherit;--shiki-dark:#4D9375;--shiki-dark-font-style:inherit}html pre.shiki code .sftqT, html code.shiki .sftqT{--shiki-light:#90A4AE;--shiki-default:#393A34;--shiki-dark:#DBD7CAEE}html pre.shiki code .soVBu, html code.shiki .soVBu{--shiki-light:#39ADB5;--shiki-default:#999999;--shiki-dark:#666666}html pre.shiki code .s5Kfy, html code.shiki .s5Kfy{--shiki-light:#9C3EDA;--shiki-default:#AB5959;--shiki-dark:#CB7676}html pre.shiki code .sD-vU, html code.shiki .sD-vU{--shiki-light:#E2931D;--shiki-default:#2E8F82;--shiki-dark:#5DA994}html pre.shiki code .sYn-s, html code.shiki .sYn-s{--shiki-light:#E2931D;--shiki-default:#59873A;--shiki-dark:#80A665}html pre.shiki code .sljsM, html code.shiki .sljsM{--shiki-light:#6182B8;--shiki-default:#59873A;--shiki-dark:#80A665}html pre.shiki code .sRjD_, html code.shiki .sRjD_{--shiki-light:#E53935;--shiki-light-font-style:italic;--shiki-default:#393A34;--shiki-default-font-style:inherit;--shiki-dark:#DBD7CAEE;--shiki-dark-font-style:inherit}html pre.shiki code .sm7ve, html code.shiki .sm7ve{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#B5695977;--shiki-default-font-style:inherit;--shiki-dark:#C98A7D77;--shiki-dark-font-style:inherit}html pre.shiki code .sVyVU, html code.shiki .sVyVU{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#B56959;--shiki-default-font-style:inherit;--shiki-dark:#C98A7D;--shiki-dark-font-style:inherit}html pre.shiki code .se3Ec, html code.shiki .se3Ec{--shiki-light:#90A4AE;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .sBPpx, html code.shiki .sBPpx{--shiki-light:#E53935;--shiki-default:#393A34;--shiki-dark:#DBD7CAEE}html pre.shiki code .siWMO, html code.shiki .siWMO{--shiki-light:#6182B8;--shiki-default:#393A34;--shiki-dark:#DBD7CAEE}html pre.shiki code .sqOPj, html code.shiki .sqOPj{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#B07D48;--shiki-default-font-style:inherit;--shiki-dark:#BD976A;--shiki-dark-font-style:inherit}html pre.shiki code .sbYkP, html code.shiki .sbYkP{--shiki-light:#39ADB5;--shiki-default:#B5695977;--shiki-dark:#C98A7D77}html pre.shiki code .sTbE_, html code.shiki .sTbE_{--shiki-light:#91B859;--shiki-default:#B56959;--shiki-dark:#C98A7D}html pre.shiki code .sa2tF, html code.shiki .sa2tF{--shiki-light:#E2931D;--shiki-default:#998418;--shiki-dark:#B8A965}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sz9Cv, html code.shiki .sz9Cv{--shiki-light:#91B859;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .s7CZa, html code.shiki .s7CZa{--shiki-light:#F76D47;--shiki-default:#2F798A;--shiki-dark:#4C9A91}html pre.shiki code .s8XtY, html code.shiki .s8XtY{--shiki-light:#39ADB5;--shiki-default:#1E754F;--shiki-dark:#4D9375}html pre.shiki code .sVsLi, html code.shiki .sVsLi{--shiki-light:#39ADB5;--shiki-default:#AB5959;--shiki-dark:#CB7676}html pre.shiki code .sCyAa, html code.shiki .sCyAa{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#393A34;--shiki-default-font-style:inherit;--shiki-dark:#DBD7CAEE;--shiki-dark-font-style:inherit}",{"title":1266,"searchDepth":1274,"depth":1281,"links":2211},[2212,2213,2214,2215,2216,2217,2218,2219,2220,2221],{"id":1032,"depth":1281,"text":1033},{"id":1070,"depth":1281,"text":1071},{"id":1101,"depth":1281,"text":1102},{"id":1132,"depth":1281,"text":1133},{"id":1169,"depth":1281,"text":1170},{"id":1215,"depth":1281,"text":1216},{"id":1255,"depth":1281,"text":1256},{"id":1786,"depth":1281,"text":1787},{"id":2160,"depth":1281,"text":2161},{"id":2198,"depth":1281,"text":2199},"md",null,{},{"title":579,"description":1028},"60X4_1BDjEih8yGSsSLPtBEMK3ie-tLVTvjxnquurJo",[2228,2230],{"title":575,"path":576,"stem":577,"description":2229,"children":-1},"Deploying Django applications securely requires careful attention to configuration, infrastructure, and operational practices. This comprehensive checklist covers all aspects of production security to ensure your application is protected against common threats and vulnerabilities.",{"title":585,"path":586,"stem":587,"description":2231,"children":-1},"Django's testing framework is built on Python's standard unittest module but provides additional functionality specifically designed for web applications. Understanding Django's testing architecture and capabilities is essential for writing effective tests that ensure your application's reliability and maintainability.",1772474940278]