1. Coding Style

A little attention to following standard coding style guidelines will go along way. We highly recommend that you read this chapter, even though you may be tempted to skip it.

1.1 The Importance of Making Your Code Readable

Code is read more than it is written.An individual block of code takes moments to write, minutes or hours to debug, and can last forever without being touched again. It's when you or someone else visits code written yesterday or ten years ago that having code written in a clear, consistent style becomes extremely useful. Understandable code frees mental bandwidth from having to puzzle out inconsistencies, making it easier to maintain and enhance projects of all size.

What this means that you shoud go the extra mile to make your code as readable as possible:

  • Avoid abbreviating variable names.
  • Write out your function argument names.
  • Document your classes and methods.
  • Comment your code.
  • Refactor repeated lines of code into reusable functions or methods.
  • Keep functions and methods short. A good rule of thumb is that scrolling should not be necessary to read an entire function or method.

When you come back to your code after time away from it, you'll have an aesier time picking up where you left off.

Take those pesky abbreviated variable names, for example. When you see a variable called `balanceseetdecrease`, it's much easier to interpret in your mind than an abbreviated variable like bsd or `balsd`. These type of shortcuts may save a few seconds of typing, but that savings comes at the expense hours or days of technical debt. It's not worth it.

1.2 PEP8

PEP8 is hte official style guide for Python. We advise reading it in detail and learn to follow the PEP8 coding conventions:(http://www.python.org/dev/peps/pep-0008\)\[http://www.python.org/dev/peps/pep-0008\]

PEP8 describes coding conventions such as:

  • "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."

All the Python files in your Django projects should follow PEP 8. If you have trouble remembering the PEP 8 guidelines, find a plugin for your code editor that checks you code as you type.

When an experienced Python programmer see gross violations of PEP 8 in a Django project, event if they don't say something mean, they are probably thinking bad things. Trust us on this one.

"""

WARNING: Don't Change an Existing Project's Conventions

The Style of PEP 8 applies to new Django project only. If you are brought into an existing Django project the follow a different convention than PEP 8, then follow the existing conventions.

Please Read the "A Foolish Consistency is the Hobgoblin of Little Minds" section of PEP 8 for details about this and other reasons to break the rules:

"""

"""

PACKAGE TIP : Use flake 8 For Checking Code Quality

Created by Tarek Ziade and now maintained by the PyCQA groups, this is a Very Useful Command-line tool for checking coding style, quality, and logic errors in projects. Us while developing locally and as a component of continuous Integration.

"""

1.2.1 The 79-Character Limit

No joke, I Still deal with consoles that are restricted to 80 characters.

-- Barry Morrison, Systems Engineer and Reviewer of every edition of this book.

According to PEP8, the limit of text per line is 79 characters. This exists because it's a safe value that most text-wrapping editors and developer teams can accommodate without hurting the understandability of code.

However, PEP 8 also has a provision for relaxing this limit to 99 characters for exclusive team projects. We interpret this to mean projects that are not open souce.

Our preference is as follow:

  • One open source projects, there should be a hard 79-character limit. Our experience has shown that contributors or visitors to these projects will grumble about line length issues.
  • On private projects, we relax the limit to 99 Characters, taking full advantage of modern monitors.

Please read (http://www.python.org/dev/peps/pep-0008/\#maximun-line-length\)

"""

TIP : Aymeric Augustin on Line Length Issues

Django core developer Aymeric Augustin says, "Fitting the code in 79 columns is never a good reason to pick worse names for variables, functions, and classes. It's much more important to have readable variable names than to fit in an arbitrary limit of hardware from three decades ago."

"""

1.3 The Word on Imports

PEP 8 suggests that imports should be grouped in the following order:

  1. standard library imports
  2. Related third-party imports
  3. Local application or library specific imports

When we're working on a Django project, our imports look something like the follwing:

"""

Example 1.1

"""

(Note: you don't actually need to comment your import like this. The comments are just here to explain the example.)

The import order in a Django projects if:

  1. Standard library imports.
  2. Import from core Django.
  3. Import from third-party apps including those unrelated to Django.
  4. Import from the apps that you created as part of your Django projects. (You'll read more about apps in chapter 4, Fundamentals of App Design.)

1.4 Use Explicit Relative Import

When writing code, it's important to do so in such a way that is easier to move, rename, and version your work. In Python, explicit relative import s remove the need for hardcoding a module's package, separating individual modules from being tightly coupled to the architecture around them. since Django apps are simply Python Packages, the same rule apply.

To illustrate the benefits of explicit relative imports, let's explore an example.

Imagine that the following snippet is from a Django Project that you created to track you ice cream consumption, including all of the waffle/sugar/cake cones that you have ever eaten.

Oh no, your cones app contains hardcoded imports, which are bad!

"""

BAD EXAMPLE 1.1

"""

Sure, your cones apps works fine within your ice cream tracker projects, but it has those nasty hardcoded imports that make it less portable and reusable:

  • What if you wanted to reuse your cones app in another project that tracks your general dessert consumption, but you had to change the name due to a naming conflict(e.g. a conflict with a Django app for snow cones)?
  • What if you simply wanted to change the name of the app at some point?

With hard coded imports, you can't just change the name of the app; you have to gid through all of the imports and change them as well. It's not hard to change them manually, but before you dismiss the need for explicit relative imports, keep in mind that the above example is extremely simple compared to a real app with various additional utility modules.

Let's now convert the bad code snippet containing hardcoded imports into a good one containing explicit relative imports. Here's the corrected example:

"""

EXAMPLE 1.2

"""

Another concrete advantage is that we can immediately tell our local/internal imports from global/external imports, highlighting the Python package as a unit of code.

"""

TIP : Use "from __future__ import absolute_import"

Python 3 updates and improves how imports work, and it does this in a good way. Fortunately, it's back-ported to Python 2.7 via the use of the from __future\_ import absolute_import statement. Event if you don't plan to use Python 3, This is a great Feature and allows for the explicit relative imports demonstrated in the table below._

"""

To summarize, here's a table of the different Python import types and when to use them in Django projects:

Code Import Type Usage
from core.views import FoodMixin absolute import Use when import from outside the current app
from .models import WaffleCone explicit relative Use when importing from another module in the current app
from models import waffleCone implicit relative Often used when importing from another module in the current app, but not a good idea

Table 1.1: Imports: Absolute vs. Explicit Relative vs. Implicit Relative

Get into the habit of using explicit relative imports. It's very easy to do, and using explicit relative imports is a good habit for any Python programmer to develop.

"""

TIP : Doesn't PEP 328 Clash With PEP 8?

See what Guido Van Rossum, BDFL of Python says about it:

"""

Additional reading: http://www.python.org/dev/peps/pep-328/

1.5 Avoid Using Import *

In 99% of all our work, we explicitly import each module:

"""

EXAMPLE 1.3

from django import forms

from django.db import models

"""

Never do the following:

"""

BAD EXAMPLE 1.2

from django.forms import *

from django.db.models import *

"""

The reason for this is to avoid implicitly loading all of another Python modules' locals into and over our current module's namespace, this can produce unpredictable and sometimes catastrophic results.

We do cover a specific exception to this rule in chapter 5, Settings and Requirements Files.

Let's look at the bad code example above. Both the Django forms and Django models libraries have a class called CharField. by implicitly loading both libraries, the models library overwrote the forms version of the class. This can also happen with Python build-in libraries and other third-party libraries overwriting critical functionality.

"""

WARNING:Python Naming Collisions

You'll run into similar problems if you try to import two things with the same name, such as:

BAD EXAPLE 1.3

from django.froms import CharField

from django.db.models import CharField

"""

Using import * is like being that greedy customer at an ice cream shop who asks for a free taster spoon of all thirty-one flavors, but who only purchases one or two scoops. Don't import everything if you're only going to use one or two things.

If the customer then walked out with a giant ice cream bowl containing a scoop of every of almost every flavor, though, it would be a different matter.

Figure 1.1: Using import * in an ice cream shop.

1.6 Django coding style

This section covers both the official guidelines as well as unofficial but commonly-accepted Django conventions.

1.6.1 Consider the Django Coding Style Guidelines

It goes without saying that it's a good idea to be aware of common Django style conventions. In fact, internally Django has its own set of style guidelines that extend PEP 8.

Additionally, while the following are not specified in the official standards, the are common enough in the Django community that you will probably want to follow them in your projects.

1.6.2 Use Underscores in URL Pattern Names Rather Than Dashes

We always try to use underscores (the "\_" character) over dashes.This isn't just more Pythonic, it's friendlier to more IDEs and text editors. Note that we are referring to the name argument of url() here, not the actual URL typed into the browser.

The wrong way, with dashes in url names:

"""

BAD EXAMPLE 1.4

"""

The right way, with underscores in url names:

"""

EXAMPLE 1.4

"""

Note that we are referring to the name argument of url() here, not the actual URL typed into the browser. Dashes in actual URLs are fine (e.g. regex='add-topping/$').

1.6.3 Use Underscores in Template Block Names Rather Than Dashes

For the same reasons as using underscores in URL pattern names, we recommend using underscores when defining names of template blocks: in this case they're more Pythonic and more editor-friendly.

1.7 Choose JS, HTML , and CSS Style Guides

1.7.1 JavaScript Style Guides

Unlike Python which has one official style guide, there is no official JaaScript Style guide. Instead, a number of unofficial JS Style guides have been created by various individuals and/or companies:

There is no consensus in the Django or JavaScript communities on any one of these, so just pick your favorite and stick with it.

However, if you are using a JavaScript framework with a style guide of its own, you should use that guide. for example, ember.js has it own style guide.

"""

PACKAGE TIP : The JSCS Code Style Linter

JSCS (http://jscs.info/\) is a tool for checking JavaScript code style. It has presets for the JS style rules of several style guides, including a few of those listed above. There are also JSCS plugins for various text editors and JSCS tsks for the Gulp and Grunt task runners.

"""

1.7.2 HTML and CSS Style Guides

"""

PACKAGE TIP : CSScomb

CSScomb (http://csscomb.com/\) is a coding style formatter for css. It checks for consistency against the rules for which you configure it for, and it checks the sort order of your CSS properties. Just as for JSCS, there are CSScomb text editor and task/build tool plugins, including for Brunch.

"""

1.8 Never Code to the IDE (Or Text Editor)

There are developers who make decisions about the layout and implementation of their projects based on the features of IDEs (Integrated Development Environment). This can make discovery of project code extremely difficult for anyone whose choice of development tool doesn't match the original author.

Alway assume that the developers around you like to use their own tools and that your code and project layout should be transparent enough that some one stuck using Notepad or Nano will be able to navigate your work.

For example, introspecting template tags or discovering their source can be difficult and time consuming for developers not using a very, very limited pool of IDEs. Therefore, we follow the commonly-used naming pattern of <app\name>_tags.py.

1.9 Summary

This chapter covered our preferred coding style and explained why we prefer each technique.

Even if you don't follow the coding style that we use, please follow a consistent coding style. Projects with varying style are much harder to maintain, slow development and increasing the changes of developer mistakes.

results matching ""

    No results matching ""