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.