In this post, I will share some tips to help you improve the design of your Django Models. Many of those tips are related to naming conventions, which can improve a lot the readability of your code.
The PEP8 is widely used in the Python ecosystem (Django included). So it’s a good idea to use it in your own projects.
Besides PEP8, I like to follow Django’s Coding Style which is a guideline for people writing code for inclusion in the Django code base itself.
Below, an overview of the items we are going to explore:
Naming Your Models
The model definition is a class, so always use CapWords convention (no underscores). E.g.
For the model’s attributes use snake_case. E.g.
Always name your models using singular. Call it
Company instead of
Companies. A model definition is the
representation of a single object (the object in this example is a company), and not a collection of companies.
This usually cause confusion because we tend to think in terms of the database tables. A model will eventually be translated into a table. The table is correct to be named using its plural form because the table represents a collection of objects.
In a Django model, we can access this collection via
Company.objects. We can renamed the
objects attribute by
So with that we would access the collection of companies as
Company.companies.filter(name='Google'). But I usually
don’t go there. I prefer keeping the
objects attribute there for consistency.
Model Style Ordering
The Django Coding Style suggests the following order of inner classes, methods and attributes:
- If choices is defined for a given model field, define each choice as a tuple of tuples, with an all-uppercase name as a class attribute on the model.
- All database fields
- Custom manager attributes
- Any custom methods
related_name attribute in the
ForeignKey fields is extremely useful. It let’s us define a meaningful name
for the reverse relationship.
Rule of thumb: if you are not sure what would be the
related_name, use the plural of the model holding the
That means the
Company model will have a special attribute named
employees, which will return a
all employees instances related to the company.
You can also use the reverse relationship to modify the
company field on the
This kind of relationship also applies to query filters. For example, if I wanted to list all companies that employs people named ‘Vitor’, I could do the following:
If you want to customize the name of this relationship, here is how we do it:
Then the usage would be:
To use it consistently,
related_name goes as plural and
related_query_name goes as singular.
Blank and Null Fields
I’ve written about the differences between Blank and Null fields in another post, but I will try to summarize it here:
- Null: It is database-related. Defines if a given database column will accept null values or not.
- Blank: It is validation-related. It will be used during forms validation, when calling
Do not use
null=True for text-based fields that are optional. Otherwise, you will end up having two possible values
for “no data,” that is: None and an empty string. Having two possible values for “no data” is redundant. The
Django convention is to use the empty string, not NULL.
Models definition is one of the most important parts of your application. Something that makes all the difference is defining the field types properly. Make sure to review the Django models field types to know your options. You can also define custom field types.
If you are interested in code conventions, I suggest having a look on Django’s Coding Style. I’ve also published an tutorial about the flake8 library which helps you check for PEP8 issues in your code.
That’s it for today! You can also subscribe to my newsletter to receive updates from the blog.