Just bought this book from feldroy.com.
GitHub for Two-Scoop-of-Django-3.x
Key Points:
- Keep It Simple, Stupid
- Fat Models, Utility Modules, Thin Views, Stupid Templates
- Follow the PEP8;
- Use 4 spaces per indentation level.
- Separate top-level function and class definitions with two blank lines.
- Method definitions inside a class are separated by a single blank line.
- Limit of text per line is 79 characters (for private projects, it is relaxed to 99 characters).
- The imports should be grouped in the following order:
- Standard library imports
- Core Django imports
- Related third-party imports
- Local application or library-specific imports
- Using aliases to avoid Python Module collisions
from django.db.models import CharField as ModelCharField
from django.forms import CharField as FormCharField
- Use underscores in URL Pattern Names rather than dashes
patterns = [
path(route='add/',
view=views.add_topping,
name='toppings:add_topping'),
]
Dashes in actual URLs are fine (e.g. route=‘add-topping/’). - Using static/ for the (non-user-generated) static media directory.
- A Django project is a web application powered by the Django web framework.
Django apps are small libraries designed to represent a single aspect of a project. A Django project is made up of many Django apps. Some of those apps are internal to the project and will never be reused; others are third-party Django packages.
INSTALLED_APPS is the list of Django apps used by a given project available in its INSTALLED_APPS setting.
Third-party Django packages are simply reusable Django apps that have been packaged with the Python packaging tools. - Each app should be tightly focused on its task.
James Bennett: “The art of creating and maintaining a good Django app is that it should follow the truncated Unix philosophy according to Douglas McIlroy: ‘Write programs that do one thing and do it well.’“ - Name the Django Apps
- Keep to single word names, like flavors, animals, blog, and finances.
- The app’s name should be a plural version of the app’s main model. There are many good exceptions, blog is the example.
- Consider naming the app according to the URLs to be appeared. For example, http://www.example.com/weblog/, then consider naming your app weblog rather than blog, posts, or blogposts, even if the main model is Post.
- Use PEP8-compliant, importable Python package names: short, all-lowercase names without numbers, dashes, periods, spaces, or special characters. Using underscores to separate words, although the use of underscores is discouraged.
- Try to keep your apps small.
- Sample Project Layout (any module ending with a slash (‘/’) represents a Python package)
yourprojname_reporoot #This is the <repository_root>.
|--config/
| |--settings/
| |--__init__.py
| |--asgi.py| |--urls.py
| |--wsgi.py
|--docs/
|--yourprojname_project/ #The <django_project_root> of the project.
| |--media/ #development only!
| |--apps1/
| |--apps2/
| |--apps3/
| |--static/ #Non-user-generated static media assets (CSS, JavaScript, and images).
| |--templates/ #Your site-wide Django templates
|--.gitignore
|--Makefile
|--README.md
|--manage.py
|--requirements.txt #Current dependencies ($ pip freeze > requirements.txt)
- When coding in Django, the classic example is the process of creating user objects and related data cross multiple models and apps.
- Service layer example
apps1/
|--api/
|--models.py
|--services.py #Service layer location for business logic
|--selectors.py #Service layer location for queries
|--tests/
- Each Django app should be tightly-focused on its own task and possess a simple, easy-to-remember name. If an app seems too complex, it should be broken up into smaller apps.
- Settings module is loaded when your server starts up.
- Instead of having one settings.py file, you have settings/ directory containing your settings files.
(Each settings module should have its own corresponding requirements file.)
settings/
|--__init__.py
|--base.py #Settings common to all instances of the project.
|--local.py #Settings file when working on the project locally.
|--staging.py #Staging version for running a semi-private version of the site on a production server.
|--test.py #Settings for running tests including test runners, in-memory database definitions, and log settings.
|--production.py #Settings file used by your live production server(s). Sometimes called prod.py.
To start Python interactive interpreter with Django, using your settings/local.py settings file:
python manage.py shell --settings=config.settings.local
To run the local development server with your settings/local.py settings file:
python manage.py runserver --settings=config.settings.local
- Never hardcoding file paths in Django settings files.
- The golden rule of Web application security is to never trust data from untrusted sources.
- Everything except for passwords and API keys ought to be tracked in version control.
- If there are 20+ models in a single app, break it down into smaller apps, as it probably means the app is doing too much.
In practice, no more than five to ten models per app. - Simple rules of thumb for knowing which type of inheritance to use and when:
- If the overlap between models is minimal, there might not be needed for model inheritance.
Just add the fields to both models. - If there is enough overlap between models, the code should be refactored so that
the common fields are in an abstract base model. - Proxy models are an occasionally-useful convenient feature, but they’re very different from
the other two model inheritance styles. - Avoid multi-table inheritance. Instead of multi-table inheritance, use explicit OneToOneFields and ForeignKeys
between models so you can control when joins are traversed.
- If the overlap between models is minimal, there might not be needed for model inheritance.
- It’s very common in Django projects to include a created and modified timestamp field on all models.
To be continued…
Further readings:
The Twelve-Factor App
PEP8 — Style Guide for Python Code