Standards

Coding

PEP-8 does not specify a standard for when to use single or double quotes, although PEP-257 specifies triple double quotes for docstrings (“””). It is important that we have a standard internally, and so it is:

  • Double quotes for text that contains substitution variables or will be printed on the screen

  • Single quotes for anything that behaves like an identifier

  • Double quoted raw string literals for regexps, e.g. re.search(r"(?i)(info|warn|error)!", message)

  • Triple double quotes (“””) for docstrings

Models

We will use standard Django ORM functionality wherever possible, together with GeoDjango for support of spatial data. Using raw SQL within the ORM is allowed if it reduces technical debt or improves performance significantly

Database tables should be generated from the definitions in Models.py by running migrations.

The following checklist lists the standards for all Models:

  • Currenty Django doesn’t support composite primary keys. Therefore, all Models must have a single specified primary key - i.e. they should not rely on an id column automatically included by Django.

  • All Models should define a __unicode__(self) function that returns a reasonable string representation of the object based on business identifiers (rather than the primary key)

  • Most models should include additional Admin app metadata in admin.py for the fields to display in lists, and the text fields to search, and possibly the fields to include in the form:

class CountryAdmin(admin.ModelAdmin):
    list_display = ('iso3166a2', 'iso3166a3', 'iso3166n3', 'local_name')
    search_fields = ['iso3166a2', 'iso3166a3', 'iso_en_name', 'iso_fr_name', 'iso_es_name']
    fields = ('iso3166a2', 'iso3166a3', 'iso3166n3', 'iso_en_name', 'iso_fr_name', 'iso_es_name')
    inlines = [CountryCurrencyInline]

admin.site.register(Country, CountryAdmin)
  • Models should be prepared for Internationalization by specifying verbose_name for models and attributes using lazy translation:

from django.utils.translation import ugettext_lazy as _

class Country(models.Model):

    class Meta:
        verbose_name = _('country')
        verbose_name_plural = _('countries')
  • The Meta class should be used exhaustively:

ordering = ['iso3166a2']
verbose_name = _('country')
verbose_name_plural = _('countries')

New Applications

New applications should be created and converted to use migrations as soon as a model is added:

./manage.py startapp xyz

After creating the app, add it to LOCAL_APPS in settings/base.py.

After you have created the first model(s) and need to deploy them, create a database migration:

::

mkdir apps/xyz/migrations touch apps/xyz/migrations/__init__.py ./manage.py makemigrations xyz ./manage.py migrate xyz

Dependencies

When a new dependency is identified it should be installed in a virtualenv working copy at the latest stable version using pip:

workon price
pip install django-model-utils

Once the new dependency has been tested the specific version used should be added to the requirements, probably to either requirements/base.txt or requirements/local.txt:

pip freeze | grep django-model-utils

Git

Our standards for Git are documented in:

Note that only tagged releases can be deployed to demo, test or production servers and tagged releases can only exist on the master branch.

See [[Release Procedures]] for more information.

Documentation

Unless otherwise noted, the master copy of all documentation is the wiki pages in Redmine available at http://projects.kimetrica.com/projects/fdw/wiki.

Derivatives such as pdfs or ReStructuredText will be produced using Redmine where possible and Pandoc otherwise (e.g. cat Standards.txt | pandoc -f markdown -t rst -o standards.rst).