How to design good Django models?

How to design good Django models?

Published 08. jul 2018 08:52 by Stein Ove Helset

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
    CABRIOLET = 2
    
    CHOICES_CHASSIS = (
        (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': self.id})
    
    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.

Share this post

Comments

No comments yet

Add comment