Download - Django Best Practices
![Page 1: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/1.jpg)
Django BestPractices
March, 2014 / Abdullah Cetin CAVDAR @accavdar
![Page 2: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/2.jpg)
This presentation is prepared based on the great book by and
Two Scoops ofDjango: Best Practices For Django 1.5 Daniel Greenfeld
Audrey Roy
![Page 3: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/3.jpg)
Core Concepts
![Page 4: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/4.jpg)
KISSKeep It Simple, Stupid
![Page 5: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/5.jpg)
Fat Models, Helper Modules,Thin Views, Stupid TemplatesPut more logic into anything but views and templatesTemplate tags and filters should contain the minimum logic possible
![Page 6: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/6.jpg)
Start With Django by DefaultIf we run into obstacles, we explore all possibilities before replacingcore Django components
![Page 7: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/7.jpg)
Coding Style
![Page 8: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/8.jpg)
The Importance of Making YourCode Readable
Avoid abbreviating variable namesGood: balance_sheet_decreaseBad: bsd or bal_s_d
Write out your function argument namesDocument your classes and methodsRefactor repeated lines of code into reusable functions or methods
![Page 9: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/9.jpg)
PEP8Use 4 spaces per indentation levelSeparate top-level function and class definitions with two blank linesMethod definitions inside a class are separated by a single blank line
![Page 10: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/10.jpg)
The Word on ImportsThe Order:
Standard library importsImports from core DjangoImports from third-party appsImports from the apps that you created as part of your Django project
![Page 11: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/11.jpg)
The Word on Imports
![Page 12: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/12.jpg)
Use Explicit Relative ImportsDon't do this:
![Page 13: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/13.jpg)
Use Explicit Relative ImportsDo this:
![Page 14: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/14.jpg)
Import Types
![Page 15: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/15.jpg)
Get into the habit of using explicit relativeimports
![Page 16: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/16.jpg)
Avoid Using Import *Don't do this:
![Page 17: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/17.jpg)
Avoid Using Import *The reason for this is to avoid implicitly loading all of another Pythonmodule’s locals into and over our current module’s namespace, which
can produce unpredictable and sometimes catastrophic results.
![Page 18: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/18.jpg)
Django Coding Style GuidelinesUse underscores (the '_' character) in URL pattern names rather thandashes as this is friendlier to more IDEs and text editors.For the same reason, use underscores rather than dashes in templateblock names.Follow the commonly used naming pattern of <app_name>_tags.pyfor template tags
Django Coding Style Guidelines
![Page 19: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/19.jpg)
SummaryFollow a consistent coding styleProjects with varying styles are much harder to maintain, slowingdevelopment and increasing the chances of developer mistakes
![Page 20: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/20.jpg)
The Optimal DjangoEnvironment Setup
![Page 21: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/21.jpg)
Use the Same Database EngineEverywhere
A common developer pitfall is using SQLite3 for local development andPostgreSQL (or another database besides SQLite3) in production.
They may not behave identical in different environments.Fixtures Are Not a Magic SolutionYou Can’t Examine an Exact Copy of Production Data LocallyDifferent Databases Have Different Field Types/Constraints
![Page 22: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/22.jpg)
Use Pip and VirtualenvPip is used to manage and install Python packagesWithout virtualenv you have to update dependency versions everytime you switch projectsIf that sounds tedious, keep in mind that most real Django projectshave at least a dozen dependencies to maintain$ source ~/Envs/udemy/bin/activate
![Page 23: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/23.jpg)
Install Django and OtherDependencies via Pip
![Page 24: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/24.jpg)
Use a Version Control System
![Page 25: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/25.jpg)
How to Layout Django Projects
![Page 26: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/26.jpg)
Prefered Project Layout
![Page 27: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/27.jpg)
Top Level: Repository RootThe top-level <repository_root>/ directory is the absolute rootdirectory of the projectPlace other critical components like the README.rst, docs/ directory,design/ directory, .gitignore, requirements.txt files, and other high-level files that are required for deployment
![Page 28: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/28.jpg)
Second Level: Django ProjectRoot
This directory contains the <configuration_root>, media and staticdirectories, a site-wide templates directory, as well as Django appsspecific to your particular project
![Page 29: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/29.jpg)
Third Level: Configuration Root<configuration_root> directory is where the settings module and baseURLConf (urls.py) are placedThis must be a valid Python package (containing an __init__.py module)
![Page 30: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/30.jpg)
Sample Project Layout
![Page 31: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/31.jpg)
What About the Virtualenv?Put all our environments in one directory and all our projects inanother
![Page 32: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/32.jpg)
TIP: Listing Current Dependenciespip freeze --local
![Page 33: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/33.jpg)
Template to Generate Layoutdjango-admin.py startproject --
template=https://github.com/twoscoops/django-twoscoops-project/zipball/master --extension=py,rst,html $project-name
![Page 34: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/34.jpg)
SummaryWhatever layout is chosen should be documented clearly
![Page 35: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/35.jpg)
Fundamentals of Django AppDesign
![Page 36: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/36.jpg)
DefinitionsA Django project is a web application powered by the Django webframeworkDjango apps are small libraries designed to represent a single aspectof a project. A Django project is made up of many Django apps. Someof those apps are internal to the project and will never be reused;others are third-party Django packages.Third-party Django packages are simply pluggable, reusable Djangoapps that have been packaged with the Python packaging tools.
![Page 37: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/37.jpg)
The Golden Rule of Django AppDesign
"Write programs that do one thing and do it well"
![Page 38: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/38.jpg)
The Golden Rule of Django AppDesign
Each app should be tightly focused on its taskIf an app can’t be explained in a single sentence of moderate length, oryou need to say 'and' more than once, it probably means the app is too
big and should be broken up
![Page 39: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/39.jpg)
What to Name Your DjangoApps
When possible keep to single word names like flavors, animals, blog,polls, dreams, estimates, and finances. A good, obvious app namemakes the project easier to maintainAs a general rule, the app’s name should be a plural version of theapp’s main model, but there are many good exceptions to this rule,blog being one of the most common onesUse valid, PEP 8-compliant, importable Python package names: short,all-lowercase names without numbers, dashes, periods, spaces, orspecial characters. If needed for readability, you can use underscoresto separate words, although the use of underscores is discouraged
![Page 40: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/40.jpg)
When in Doubt, Keep AppsSmall
Try and keep your apps small. Remember, it’s better to have many smallapps than to have a few giant apps.
![Page 41: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/41.jpg)
SummaryEach Django app should be tightly-focused on its own task, possess asimple, easy-to-remember nameIf an app seems too complex, it should be broken up into smaller apps
![Page 42: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/42.jpg)
Settings and RequirementsFiles
![Page 43: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/43.jpg)
Best PracticesAll settings files need to be version-controlled
This is especially true in production environments, where dates,times, and explanations for settings changes absolutely must betracked
Don’t Repeat YourselfYou should inherit from a base settings file rather than cutting-and-pasting from one file to another
Keep secret keys safeThey should be kept out of version control
![Page 44: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/44.jpg)
Avoid Non-Versioned LocalSettings
Let’s break up development, staging, test, and production settings intoseparate components that inherit from a common base file all tracked
by version control
![Page 45: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/45.jpg)
Using Multiple Settings Files
![Page 46: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/46.jpg)
![Page 47: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/47.jpg)
TIP: Multiple Files with Continuous Integration Servers
You’ll also want to have a ci.py module containing that server’s settings.
![Page 48: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/48.jpg)
Run Serverpython manage.py runserver --settings=udemy.settings.local
![Page 49: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/49.jpg)
--settings orDJANGO_SETTINGS_MODULE
![Page 50: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/50.jpg)
DEV Settings Example
![Page 51: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/51.jpg)
Keep Secret Keys Out with EnvironmentVariables
Secrets often should be just that: secret! Keeping them in versioncontrol means that everyone with repository access has access tothemSecret keys are configuration values, not code
![Page 52: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/52.jpg)
To resolve this, our answer is touse environment variables
![Page 53: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/53.jpg)
Benefits of Using EVKeeping secrets out of settings allows you to store every settings file inversion control without hesitation. All of your Python code reallyshould be stored in version control, including your settingsInstead of each developer maintaining an easily-outdated, copy-and-pasted version of the local_settings.py.example file for their owndevelopment purposes, everyone shares the same version-controlledsettings/local.pySystem administrators can rapidly deploy the project without havingto modify files containing Python codeMost platforms-as-a-service recommend the use of environmentvariables for configuration and have built-in features for setting andmanaging them
![Page 54: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/54.jpg)
Local Settings & Usage
![Page 55: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/55.jpg)
Using Multiple RequirementsFiles
First create a requirements/ directory in the <repository_root>Then create '.txt' files that match the contents of your settingsdirectory
![Page 56: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/56.jpg)
Sample Configbase.txt
local.txt
![Page 57: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/57.jpg)
Install From Reqs Filefor development env
for production env
![Page 58: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/58.jpg)
Handling File Paths in SettingsDon't hardcode your paths
![Page 59: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/59.jpg)
Hardcoded PathsDon't do this:
![Page 60: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/60.jpg)
Relative Paths with UnipathDo this:
![Page 61: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/61.jpg)
Relative Paths with Std LibsDo this:
![Page 62: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/62.jpg)
SummaryEverything except for critical security related values ought to betracked in version controlAny project that’s destined for a real live production server is bound toneed multiple settings and requirements filesThe same thing applies to requirements files. Working with untrackeddependency differences increases risk as much as untracked settings
![Page 63: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/63.jpg)
Database/Model Best Practices
![Page 64: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/64.jpg)
BasicsBreak Up Apps With Too Many ModelsDon’t Drop Down to Raw SQL Until It’s NecessaryAdd Indexes as NeededBe Careful With Model InheritanceUse South for Migrations
![Page 65: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/65.jpg)
Consider Adding Indexes?The index is used frequently, as in 10-25% of all queriesThere is real data, or something that approximates real data, so wecan analyze the results of indexingWe can run tests to determine if indexing generates an improvementin results
![Page 66: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/66.jpg)
Django Model InheritanceNo Model Inheritance if models have a common field, give both models
that fieldPro: Makes it easiest to understand at a glance how Django modelsmap to database tablesCon: If there are a lot of fields duplicated across models, this can behard to maintain
![Page 67: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/67.jpg)
Django Model InheritanceAbstract base classes tables are only created for derived models
Pro: Having the common fields in an abstract parent class saves usfrom typing them more than once. We don’t get the overhead of extratables and joins that are incurred from multi-table inheritanceCon: We cannot use the parent class in isolation
![Page 68: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/68.jpg)
Django Model InheritanceMulti-table inheritance tables are created for both parent and child. An
implied OneToOneField links parent and childPro: Gives each model its own table, so that we can query eitherparent or child model. Also gives us the ability to get to a child objectfrom a parent object: parent.childCon: Adds substantial overhead since each query on a child tablerequires joins with all parent tables. We strongly recommend againstusing multi-table inheritance
![Page 69: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/69.jpg)
Django Model InheritanceProxy Models a table is only created for the original model
Pro: Allows us to have an alias of a model with different PythonbehaviorCon: We cannot change the model’s fields
![Page 70: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/70.jpg)
WARNING: Avoid Multi-TableInheritance
Multi-table inheritance, sometimes called "concrete inheritance" isconsidered by the authors and many other developers to be a bad thing.
We strongly recommend against using it
![Page 71: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/71.jpg)
Django Model Design
![Page 72: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/72.jpg)
Design BasicsStart NormalizedCache Before DenormalizingDenormalize Only if Absolutely NeededWhen to Use Null and Blank
![Page 73: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/73.jpg)
Null vs. Blank
![Page 74: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/74.jpg)
Model Managers
![Page 75: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/75.jpg)
Model Managers BasicsEvery time we use the Django ORM to query a model, we are using an
interface called a model manager to interact with the databaseDjango provides a default model manager for each model class, but we
can define our own
![Page 76: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/76.jpg)
Custom Model Manager
![Page 77: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/77.jpg)
Custom Model Manager
![Page 78: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/78.jpg)
SummaryTake the time to design models thoughtfullyStart normalized, and only denormalize if you’ve already exploredother options thoroughlyTry to address your performance issues with cachingDon’t forget to use indexes. Add indexes when you have a better feelIf you decide to use model inheritance, inherit from abstract baseclasses rather than concrete models. You’ll save yourself from theconfusion of dealing with implicit, unneeded joinsUse South to manage your data and schema migrations
![Page 79: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/79.jpg)
Function- and Class- BasedViews
![Page 80: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/80.jpg)
When to use FBV or CBVs
![Page 81: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/81.jpg)
Keep View Logic Out ofURLConfs
The views modules should contain view logicThe URL modules should contain URL logic
![Page 82: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/82.jpg)
![Page 83: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/83.jpg)
Stick to Loose Coupling inURLConfs
![Page 84: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/84.jpg)
![Page 85: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/85.jpg)
![Page 86: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/86.jpg)
Best PracticesDon’t Repeat Yourself: No argument or attribute is repeated betweenviewsLoose coupling: We’ve removed the model and template names fromthe URLConf because views should be views and URLConfs should beURLConfs. We should be able to call our views from one or moreURLConfs, and our approach lets us do just thatURLConfs should do one thing and do it well: Related to our previousbullet, our URLConf is now focused primarily on just one thing: URLrouting. We aren’t tracking down view logic across both views andURLConfs, we just look in our viewsOur views benefit from being class-based: Our views, by having aformal definition in the views module, can inherit from other classes.This means adding authentication, authorization, new contentformats, or anything other business requirement tossed our way ismuch easier to handleInfinite flexibility: Our views, by having a formal definition in the viewsmodule, can implement their own custom logic
![Page 87: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/87.jpg)
Try to Keep Business Logic Outof Views
Placing so much logic in our views made it much harder to deliver newformats such as PDF or REST APIBusiness logic is placed into easily reusable components, and calledfrom within views, it makes extending components of the project todo more things much easier
![Page 88: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/88.jpg)
Best Practices for Class-BasedViews
![Page 89: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/89.jpg)
Guideline when writing CBVsLess view code is betterNever repeat code in viewsViews should handle presentation logic. Try to keep business logic inmodels when possible, or in forms if you mustKeep your views simpleKeep your mixins simpler
![Page 90: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/90.jpg)
Mixin RulesThe base view classes provided by Django always go to the rightMixins go to the left of the base viewMixins should inherit from Python’s built-in object type
![Page 91: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/91.jpg)
![Page 92: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/92.jpg)
Django CBVs
![Page 93: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/93.jpg)
Constraining Django CBV Access toAuthenticated Users
PS: It uses braces lib
![Page 94: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/94.jpg)
Things to Know About Forms
![Page 95: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/95.jpg)
Statistics95% of Django projects should use ModelForms91% of all Django projects use ModelForms80% of ModelForms require trivial logic20% of ModelForms require complicated logic
![Page 96: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/96.jpg)
Use the POST Method in HTMLForms
Every HTML form that alters data must submit its data via the POSTmethod
The only exception you’ll ever see to using POST in forms is with searchforms, which typically submit queries that don’t result in any alteration
of data.
![Page 97: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/97.jpg)
Know How Form Validation WorksWhen you call form.is_valid(), a lot of things happen behind the scenes.
The following things occur according to this workflow:If the form has bound data, form.is_valid() calls the form.full_clean()methodform.full_clean() iterates through the form fields and each fieldvalidates itself:
Data coming into the field is coerced into Python via theto_python() method or raises a ValidationErrorData is validated against field-specific rules, including customvalidators. Failure raises a ValidationErrorIf there are any custom clean_ <field>() methods in the form, theyare called at this time
form.full_clean() executes the form.clean() methodIf it’s a ModelForm instance, form._post_clean() does the following:
Sets ModelForm data to the Model instance, regardless of whetherform.is_valid() is True or FalseCalls the model’s clean() method. For reference, saving a modelinstance through the ORM does not call the model’s clean() method
![Page 98: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/98.jpg)
Form Data Is Saved to the Form, Then theModel Instance
First, form data is saved to the form instanceLater, form data is saved to the model instance
![Page 99: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/99.jpg)
SummaryOnce you dig into forms, keep yourself focused on clarity of code and
testability
![Page 100: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/100.jpg)
Building REST APIs in Django
![Page 101: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/101.jpg)
Fundamentals of Basic RESTAPI Design
![Page 102: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/102.jpg)
NotesIf you’re implementing a read-only API, you might only need toimplement GET methodsIf you’re implementing a read-write API you must at least also usePOST, but should also consider using PUT and DELETEBy definition, GET, PUT, and DELETE are idempotent. POST andPATCH are notPATCH is often not implemented, but it’s a good idea to implement itif your API supports PUT requests
![Page 103: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/103.jpg)
Status Codes
![Page 104: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/104.jpg)
Implementing a Simple JSON APIUse django-rest-framework
![Page 105: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/105.jpg)
![Page 106: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/106.jpg)
![Page 107: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/107.jpg)
![Page 108: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/108.jpg)
![Page 109: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/109.jpg)
REST API Architecture
![Page 110: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/110.jpg)
Code for an App Should Remain in the AppREST API views should go into views.py modules and follow the same
guidelines we endorse when it comes to any other viewThe same goes for app or model specific serializers and renderers.
![Page 111: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/111.jpg)
Try to Keep Business Logic Out of APIViews
It’s a good idea to try to keep as much logic as possible out of API views
![Page 112: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/112.jpg)
Grouping API URLsHow do you build a project-wide API that looks like this?
![Page 113: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/113.jpg)
SolutionWhen building a project-wide API we write the REST views in the
views.py modules, wire them into a URLConf called something likecore/api.py or core/apiv1.py and include that from the project root’s
urls.py module
![Page 114: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/114.jpg)
![Page 115: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/115.jpg)
Templates: Best Practices
![Page 116: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/116.jpg)
Follow a Minimalist ApproachFind simple, elegant ways to put more of your business logic into Python
code rather than into templates
![Page 117: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/117.jpg)
Template Architecture Patterns2-Tier Template Architecture Example3-Tier Template Architecture Example
![Page 118: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/118.jpg)
2-Tier Template ArchitectureExample
![Page 119: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/119.jpg)
3-Tier Template ArchitectureExample
![Page 120: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/120.jpg)
Flat Is Better Than NestedComplex template hierarchies make it exceedingly difficult to debug,
modify, and extend HTML pages and tie in CSS stylesWhen you have large, multi-line chunks of the same or very similar code
in separate templates, refactoring that code into reusable blocks willmake your code more maintainable.
![Page 121: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/121.jpg)
Template Best PracticesLimit Processing in Templates
Try to think about caching to handle template inefficienciesDon't Aggregate in Templates
Ex: Birth Date -> AgeDon't Filter With Conditionals in TemplatesDon't Use Complex Implied Queries in TemplatesAvoid Hidden CPU Load in Templates
Ex: Take image processing out of templates and into views,models, helper methods, or asynchronous messages queues likeCelery
Avoid Hidden REST API Calls in TemplatesAn example is querying an unfortunately slow maps API hosted bya third-party service
![Page 122: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/122.jpg)
Don't Filter With Conditionals inTemplates
Don't do this:
![Page 123: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/123.jpg)
Don't Filter With Conditionals inTemplates
Do this:
![Page 124: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/124.jpg)
Don't Filter With Conditionals inTemplates
Do this:
![Page 125: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/125.jpg)
Don't Use Complex ImpliedQueries in Templates
Don't do this:
![Page 126: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/126.jpg)
Don't Use Complex ImpliedQueries in Templates
Use select_related() methodDo this:
![Page 127: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/127.jpg)
Exploring Template Inheritance
![Page 128: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/128.jpg)
Template Tags
![Page 129: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/129.jpg)
![Page 130: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/130.jpg)
![Page 131: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/131.jpg)
Template Objects
![Page 132: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/132.jpg)
{block super}
![Page 133: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/133.jpg)
Use URL Names Instead of HardcodedPaths
![Page 134: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/134.jpg)
Trade offs of Replacing CoreComponents
![Page 135: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/135.jpg)
Short Answer: Don’t do it
![Page 136: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/136.jpg)
Dealing with the User Model
![Page 137: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/137.jpg)
Finding the User Model
![Page 138: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/138.jpg)
Use settings.AUTH_USER_MODEL forForeign Keys
![Page 139: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/139.jpg)
Custom User ModelOption 1: Linking Back From a Related ModelOption 2: Subclass AbstractUserOption 3: Subclass AbstractBaseUser
![Page 140: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/140.jpg)
Linking Back From a Related Model
![Page 141: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/141.jpg)
Subclass AbstractUser
![Page 142: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/142.jpg)
Subclass AbstractBaseUserAbstractBaseUser is the bare-bones option with only 3 fields: password,
last_login, and is_activeChoose this option if:
You’re unhappy with the fields that the User model provides bydefault, such as first_name and last_nameYou prefer to subclass from an extremely bare-bones clean slate butwant to take advantage of the AbstractBaseUser sane defaultapproach to storing passwords
Official Doc: Customizing User
![Page 143: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/143.jpg)
![Page 144: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/144.jpg)
SummaryDepending on the needs of a project, they can either continue with the
current way of doing things or customize the actual user model
![Page 145: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/145.jpg)
Testing
![Page 146: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/146.jpg)
Useful Libraries For Testing DjangoProjects
Use coverage.py and django-discover-runner
![Page 147: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/147.jpg)
How to Structure TestsThe first thing we do is delete the default but useless tests.py module
that django-admin.py startapp createsIn its place, we create a tests directory and place an __init__.py file in it so
it becomes a valid Python module. Then, inside the new tests module,because most apps need them, we create test_forms.py, test_models.py,test_views.py modules. Tests that apply to forms go into test_forms.py,
model tests go into test_models.py, and so on
![Page 148: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/148.jpg)
Test Structure
![Page 149: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/149.jpg)
TIP: Prefix Test Modules With test_It’s critically important that we always prefix test modules with test_,
otherwise we can’t configure django-discover-runner to discover just ourtest files.
![Page 150: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/150.jpg)
How to Write Unit Tests
![Page 151: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/151.jpg)
Each Test Method Tests One ThingA single test should assert the behavior of a single view, model, form,
method or functionBe absolutely minimalistic when constructing the environment
![Page 152: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/152.jpg)
Don’t Write Tests That Have to Be TestedTests should be written as simply as possible. If the code in a test or
called to help run a test feels complicated or abstracted, then you havea problem
Don’t Repeat Yourself Doesn’t Apply to Writing Tests
![Page 153: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/153.jpg)
PACKAGE TIP: Tools to Generate Test Datafactory_boy A package that generates model test datamodel_mommy Another package that generates model test datamock Not explicitly for Django, this allows you to replace parts of yoursystem with mock objects
![Page 154: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/154.jpg)
Things That Should Be Tested
EverythingViews, Models, Forms, Validators, Filters, Signals, Template Tags, ...
![Page 155: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/155.jpg)
Continuous Integration (CI)For medium and large projects, we recommend setting up a continuous
integration (CI) server to run the project’s test suite whenever code iscommitted and pushed to the project repo
![Page 156: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/156.jpg)
Test CoverageTry to get test coverage as high as possible. Every work day we increaseour test coverage is a victory, and every day the coverage goes down is a
loss
![Page 157: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/157.jpg)
Setup a Test RunnerCreate a settings/test.py module and add the following
![Page 158: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/158.jpg)
Run Tests and Generate Coverage Report
![Page 159: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/159.jpg)
Generate Report
![Page 160: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/160.jpg)
Playing the Game of Test CoverageThe game has a single rule:
Mandate that no commit can lower testcoverage
![Page 161: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/161.jpg)
Finding and ReducingBottlenecks
![Page 162: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/162.jpg)
Speed Up Query-Heavy PagesUse django-debug-toolbar to help you determine where most of yourqueries are coming from. Configure it to include the SQLDebugPanelAdd django-cache-panel to your project, but only configured to runwhen settings/dev.py module is called. This will increase visibility intowhat your cache is doingdjango-extensions comes with a tool called RunProfileServer thatstarts Django’s runserver command with hotshot/profiling toolsenabledReduce the Number of Queries
Use select_related() in your ORMImplement caching using a key/value store such as Memcached
Speed Up Common Queries
![Page 163: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/163.jpg)
TIP: Use EXPLAIN ANALYZE / EXPLAINIf you’re using PostgreSQL, you can use EXPLAIN ANALYZE to get an
extremely detailed query plan and analysis of any raw SQL query. TheMySQL equivalent is the EXPLAIN command, which isn’t as detailed but
is still helpful
![Page 164: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/164.jpg)
Get the Most Out of Your DatabaseDon’t add logs to the database. They will slow DB performanceDon’t store ephemeral data in the database. This includes examplessuch as django.contrib.sessions, django.contrib.messages, andmetrics. Instead, move this data to things like Memcached, Redis,Riak, and other non-relational storesTry performance tuning for your database (ex: MySQL)
![Page 165: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/165.jpg)
Cache Queries With Memcached or RedisSimply setting up Django’s built-in caching system with Memcached or
Redis
![Page 166: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/166.jpg)
Identify Specific Places to CacheWhich views/templates contain the most queries?Which URLs are being requested the most?When should a cache for a page be invalidated?
![Page 167: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/167.jpg)
Consider Third-Party Caching PackagesAdditional Features of 3rd party packages:
Caching of QuerySetsCache invalidation settings/mechanismsAlternative or experimental approaches to cachingEx: django-cache-machine, johnny-cache
![Page 168: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/168.jpg)
Compression and Minification of HTML,CSS, and JavaScript
Django provides tools for you: GZipMiddleware and the {% spaceless %}template tag. However, compression and minification take up system
resources, which can create bottlenecks of their ownA better approach is to use Apache and Nginx web servers configured to
compress the outgoing content
![Page 169: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/169.jpg)
Use Upstream Caching or a ContentDelivery Network
Upstream caches such as Varnish are very useful. They run in front ofyour web server and speed up web page or content serving significantlyContent Delivery Networks (CDNs) like Akamai and Amazon Cloudfront
serve static media such as images, video, CSS, and JavaScript files
![Page 170: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/170.jpg)
Security Best Practices
![Page 171: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/171.jpg)
Harden Your ServersChange your SSH port and disable/remove unnecessary services
![Page 172: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/172.jpg)
Know Django’s Security FeaturesDjango has lots of security features. Know how to configure them.
Django security features include:Cross-site scripting (XSS) protectionCross-site request forgery (CSRF) protectionSQL injection protectionClickjacking protectionSupport for SSL/HTTPS, including secure cookiesValidation of files uploaded by usersSecure password storage, using the PBKDF2 algorithm with a SHA256hash by defaultAutomatic HTML escaping
![Page 173: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/173.jpg)
Turn Off DEBUG Mode in ProductionYour production site should not be running in DEBUG mode
![Page 174: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/174.jpg)
Keep Your Secret Keys SecretKeep Secret Keys Out With Environment Variables
![Page 175: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/175.jpg)
HTTPS EverywhereIt is always better to deploy a site behind HTTPSTwo packages that force HTTPS/SSL across your entire site throughDjango middleware
django-sslifydjango-secure
![Page 176: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/176.jpg)
Use HTTP Strict Transport Security (HSTS)When you enable HSTS, your site’s web pages include a HTTP header
that tells HSTS-compliant browsers to only connect to the site via secureconnections:
![Page 177: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/177.jpg)
Use Secure CookiesYour site’s cookies should also be served over HTTPS. You’ll need to set
the following in your settings:HSTS-compliant browsers will redirect HTTP links to HTTPSIf a secure connection isn’t possible (e.g. the certificate is self-signed orexpired), an error message will be shown and access will bedisallowed
![Page 178: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/178.jpg)
Use Django’s Allowed Hosts ValidationYou must set ALLOWED_HOSTS in your settings to a list of allowed
host/domain names. This is a security measure to prevent use of fakeHTTP Host headers to submit requests
![Page 179: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/179.jpg)
Always Use CSRF Protection With HTTPForms That Modify Data
Django comes with Cross-site Request Forgery Protection (CSRF) built inYou should use Django’s CsrfViewMiddleware as blanket protection
across your site rather than manually decorating views with csrf_protect
![Page 180: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/180.jpg)
Prevent Against Cross-Site Scripting (XSS)Attacks
Django by default escapes a lot of specific characters meaning mostattacks fail
![Page 181: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/181.jpg)
Defend Against Python Code InjectionAttacks
Beware of the eval(), exec(), and execfile() built-ins. If your projectallows arbitrary strings or files to be passed into any of thesefunctions, you are leaving your system open to attackNever unpickle data received from an untrusted or unauthenticatedsourceValidate All User Input With Django Forms
![Page 182: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/182.jpg)
Handle User-Uploaded Files CarefullyPay close attention to where you’re uploading them and what type offiles they are, to avoid security holesUse the python-magic library to check the uploaded file’s headers
![Page 183: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/183.jpg)
Don’t Use ModelForms.Meta.excludeWhen using ModelForms, always use Meta.fields. Never use
Meta.exclude. The use of Meta.exclude is considered a grave securityrisk. We can’t stress this strongly enough. Don’t do it
![Page 184: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/184.jpg)
Meta.fields vs. Meta.exclude
![Page 185: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/185.jpg)
Beware of SQL Injection AttacksThe Django ORM generates properly-escaped SQL which will protectyour site from users attempting to execute malignant, arbitrary SQL
codeWhen using raw SQL, be especially careful to escape your SQL code
properly
![Page 186: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/186.jpg)
Never Store Credit Card DataWe recommend using third-party services like Stripe, Balanced
Payments, PayPal, and others that handle storing this information foryou
![Page 187: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/187.jpg)
Secure the Django AdminSince the Django admin gives your site admins special powers thatordinary users don’t have, it’s good practice to make it extra secure
Change the Default Admin URLUse django-admin-honeypotOnly Allow Admin Access via HTTPSLimit Admin Access Based on IP
![Page 188: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/188.jpg)
Monitor Your SitesCheck your web servers’ access and error logs regularly. Install
monitoring tools and check on them frequently
![Page 189: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/189.jpg)
Keep Your Dependencies Up-to-DateYou should always update your projects to work with the latest stable
release of Django. This is particularly important when a release includessecurity fixes
![Page 190: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/190.jpg)
Put Up a Vulnerability Reporting PageIt’s a good idea to publish information on your site about how users can
report security vulnerabilities to you
![Page 191: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/191.jpg)
Logging
![Page 192: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/192.jpg)
When to Use Each Log LevelLOG Levels: DEBUG, INFO, WARNING, ERROR, and CRITICAL
In your production environment, we recommend using every log levelexcept for DEBUG
![Page 193: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/193.jpg)
Log Catastrophes With CRITICALEx: if your code relies on an internal web service being available, and ifthat web service is part of your site’s core functionality, then you mightlog at the CRITICAL level anytime that the web service is inaccessible
![Page 194: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/194.jpg)
Log Production Errors With ERRORWe recommend that you use the ERROR log level whenever you need tolog an error that is worthy of being emailed to you or your site admins
![Page 195: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/195.jpg)
Log Lower-Priority Problems WithWARNING
This level is good for logging events that are unusual and potentiallybad, but not as bad as ERROR-level events
Ex: if you are using django-admin-honeypot to set up a fake admin/login form, you might want to log intruders' login attempts to this level
![Page 196: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/196.jpg)
Log Useful State Information With INFOStartup and shutdown of important components not loggedelsewhereState changes that occur in response to important eventsChanges to permissions, e.g. when users are granted admin access
![Page 197: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/197.jpg)
Log Debug-Related Messages to DEBUG
![Page 198: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/198.jpg)
Log Tracebacks When Catching ExceptionsLogger.exception() automatically includes the traceback and logs atERROR levelFor other log levels, use the optional exc_info keyword argument
![Page 199: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/199.jpg)
One Logger Per Module That Uses LoggingWhenever you use logging in another module, don’t import and reuse a
logger from elsewhere. Instead, define a new logger specific to themodule like this
![Page 200: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/200.jpg)
Log Locally to Rotating FilesA common way to set up log rotation is to use the UNIX logrotate utility
with logging.handlers.WatchedFileHandler
![Page 201: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/201.jpg)
Other Logging TipsControl the logging in settings files per the Django documentation onloggingWhile debugging, use the Python logger at DEBUG levelAfter running tests at DEBUG level, try running them at INFO andWARNING levels. The reduction in information you see may help youidentify upcoming deprecations for third-party librariesDon’t wait until it’s too late to add logging. You’ll be grateful for yourlogs if and when your site failsUse logutils utility for advanced logging features
![Page 202: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/202.jpg)
Random Utilities
![Page 203: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/203.jpg)
Create a Core App for Your UtilitiesOur way of handling our utilities is to place them into a Django app
called core that contains modules which contains functions and objectsfor use across a project
![Page 204: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/204.jpg)
Django’s Own Swiss Army KnifeDjango has a number of useful helper functions that don’t have a better
home than the django.utils package
![Page 205: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/205.jpg)
django.contrib.humanizehis is a set of localized template filters designed to give user presented
data a more 'human' touch
![Page 206: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/206.jpg)
django.utils.html.remove_tags(value,tags)
When you need to accept content from users and want to strip out a listof tags, this function removes those tags for you while keeping all other
content untouched
![Page 207: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/207.jpg)
django.utils.html.strip_tags(value)When you need to accept content from users and have to strip out
anything that could be HTML, this function removes those tags for youwhile keeping all the existing text between tags
![Page 208: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/208.jpg)
django.utils.text.slugify(value)Whatever you do, don’t write your own version of the slugify() function;
as any inconsistency from what Django does with this function will causesubtle yet nasty problems. Instead, use the same function that Django
uses and slugify() consistently
![Page 209: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/209.jpg)
django.utils.timezoneWhen you use Django’s time zone support, date and time information isstored in the database uniformly in UTC format and converted to local
time zones as needed
![Page 210: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/210.jpg)
django.utils.translationMuch of the non-English speaking world appreciates use of this tool, as
it provides Django’s i18n support
![Page 211: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/211.jpg)
Deploying Django Projects
![Page 212: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/212.jpg)
Using Your Own Web ServersYou should deploy your Django projects with WSGI
Most common setup:Gunicorn behind a Nginx proxyApache with mod_wsgi
![Page 213: Django Best Practices](https://reader030.vdocuments.us/reader030/viewer/2022032421/55a864401a28ab3e238b4662/html5/thumbnails/213.jpg)
Quick Comparison