How to design good Django models?

/ #Django

Designing good Django models is very important when it comes to readability and to maintainability. In this post I'll share some good tips on how to implement some good techniques.

A Django model example

from django.db import models

class Car(models.Model):
    brand = models.CharField(max_length=40)
    doors = models.IntegerField(default=5)
    color = models.CharField(max_length=30)

It's important and a good practice to use singular name on your models. Use Car and not Cars, this is because the model represent a single object of the Car and not all the cars in your database. It's also important to notice that the model definition is a class and then we use CamelCase to name them. Examples: Car, CarCompany. The attributes are named with snake_case. Examples: brand, brand_name.

How to structure the model

The coding style from Django suggest that we use this order when we set up the model:

  • Choices
  • The attributes
  • The meta class
  • String method
  • Custom save method
  • Absolute url method
  • Other custom methods you need

Here is an example of a Django model with all fields:

from django.db import models
from django.urls import reverse

class Car(models.Model):
    SEDAN = 0
    COMBI = 1
        (SEDAN, 'Sedan'),
        (COMBI, 'Combi'),
        (CABRIOLET, 'Cabriolet')
    brand = models.CharField('Brand', max_length=40)
    chassis = models.IntegerField('Chassis', choices=CHOICES_CHASSIS)
    class Meta:
        ordering = ('name',)
    def __str__(self):
        return self.brand
    def save(self, *args, **kwargs):
        perform_action() # Perform custom action
        super().save(*args, **kwargs) # Perform the actual save
    def get_absolute_url(self):
        return reverse('car_detail', kwargs={'pk':})
    def perform_action():
        print('This is a action called from the custom save method')

Django's ForeignKey

A very cool thing about the ForeignKey(Reverse relationship) is that you can define something called a "related_name". This let's you add a name to the relationship that is actually meaningful.

Here is an example on how to use the ForeignKey:

from django.db import models

class Brand(models.Model):
    name = models.CharField('Brand', max_length=40)

class Model(models.Model):
    name = models.CharField('Name', max_length=50)
    brand = models.ForeignKey(Brand, on_delete=models.CASCADE, related_name='models')

# How to use in a QuerySet

brand = Brand.objects.get(name='BMW')
models = brand.models.all()

The blanks and the null

What is the difference between null and blank?
null = this is the database value. If you set null=True the database will accept null as value.
blank = this is django validation on the field. If you set blank=False (this is default) and you use this in a form, a error will be displayed if the value is empty.

If you want to read more about Django's models I would suggest to get the book Two Scoops of Django. They have written so much good information on the subject.


No comments yet...

Add comment


Subscribe to my weekly newsletter. One time per week I will send you a short summary of the tutorials I have posted in the past week.