Django / Python Code Standards¶
- Click here for Standards
- Click here for Documentation
- Click here for Security Standards - Development
- Click here for Sys-Admin and Configuration Management
- Click here for Technology Standards
- Click here for UI Standards
These documents are very good starting points:
Add the following to
black pytest-cov pytest-flakes pytest-pep8 white
Add configuration for flakes e.g in
[tool:pytest] addopts= --ds=settings.dev_test --cov-report html --reuse-db --fail-on-template-vars norecursedirs = .git venv-* src node_modules # 1. migrations always import models # 2. custom settings files e.g. 'dev_patrick.py' do 'from .base import *' # 3. 'test_view_perm.py' py.test fixtures conflict with pyflakes flakes-ignore = block/migrations/* UnusedImport example_block/dev_*.py ImportStarUsed test_view_perm.py UnusedImport RedefinedWhileUnused
block to the correct path for your app or project.
DJANGO_SETTINGS_MODULE was being ignored. To fix, add
addopts= --ds=settings.dev_test --cov-report html... to
addopts and remove
To format the code:
Create a separate commit for code formatting.
To check the code:
py.test --flakes py.test --pep8
- (not sure if this project is any good). If it is… check with https://github.com/mgedmin/check-manifest
GIT Commit Messages¶
The seven rules of a great git commit message:
- Separate subject from body with a blank line
- Limit the subject line to 50 characters
- Capitalize the subject line
- Do not end the subject line with a period
- Use the imperative mood in the subject line
- Wrap the body at 72 characters
- Use the body to explain what and why vs. how
And my favourite piece of advice:
A properly formed git commit subject line should always be able to complete the following sentence:
If applied, this commit will your subject line here
The order of model inner classes and standard methods should be as follows (they are not all required):
- All database fields
- Custom manager attributes
- Any custom methods
We don’t delete data (unless there is a specific requirement for it).
We have a TimedCreateModifyDeleteModel which sets up the fields.
To mark an object as deleted in a Django view, see UpdateView not DeleteView
File and Image Field¶
ImageField, then set the
upload_to path to
reflect the app and model name e.g. for the
document field in the
Attachment model in the
document = models.FileField(upload_to='mail/attachment/')
.gitlab-ci.yml file in the root of the project e.g:
requirements/ci.txt file e.g:
To make access easier for public repositories, use the GIT
URL rather than a path to the folder e.g:
Check the project
setup.cfg file to make sure
src is included in the
norecursedirs section e.g:
norecursedirs = .git angular venv-* src
Commit and push to GitLab.
In GitLab logged in as the project owner:
- Select: Settings | General and expand the Permissions section and set:
Repository, Pipelines to
Only Project Members.
- Select: Settings, CI/CD Pipelines and expand the Runners section and: Disable shared runners for this project.
- Still in Settings, CI/CD Piplines expand the “General Pipeline settings
and set Test coverage parsing to
\d+\%\s*$(copy the pytest-cov (Python) example).
For email notifications for the project, Settings, Integrations, Pipelines emails. Tick Active, add Recipients and Add pusher
Test settings on Builds emails threw an error last time I tried, but the email still sends OK.
Model factories should create the minimum required to construct a valid object e.g. a product will probably need to create a product category, but a contact will not need to fill in the date of birth.
I am not 100% sure about this… but I am sure a factory which does more than it needs to will make it feel like magic is going on and cause confusion.
We use the
import attr from unittest.mock import patch @attr.s class StripeCustomer: id = attr.ib() @patch("stripe.Charge.create") @patch("stripe.Customer.create", return_value=StripeCustomer(id="xyz")) @pytest.mark.django_db def test_payment(mock_charge, mock_customer, client): _check_success(client) assert mock_charge.called is True assert mock_customer.called is True
We also use
Following Cameron Maske’s tweet ref So many different ways to mock an HTTP request in Python, I am now testing the responses library for mocking HTTP requests…
The following (ref
httmock) is an old note…
When we next do HTTP/API testing, then checkout https://github.com/patrys/httmock
It was recomended in this talk: Django and the testing pyramid - DjangoCon Europe 2017.
From Coding Conventions:
url(regex=r'^$', view=views.poll_list, name='poll_list', ),
… the preferred and wonderfully explicit Jacob Kaplan-Moss / Frank Wiles pattern…
Probably best to use the actual view class rather than just the name,
view='polls.views.standard.poll_list',, makes it harder to
debug on errors.