CodeNewbie Community ๐ŸŒฑ

Cover image for Designing Better Models in Django
Vicente Antonio G. Reyes
Vicente Antonio G. Reyes

Posted on • Originally published at vgr.icvn.tech

Designing Better Models in Django

Photo by Christopher Gower on Unsplash

Introduction

Defining database models is the most critical part of a new project. Djangoโ€™s coding style ives us a recommended way to create models for our apps which I only discovered today thanks to LearnDjango.๐Ÿ˜ Creating database models may not be simple to devs who havenโ€™t laid hands on Django yet, but Iโ€™ll try my best to make sense. ๐Ÿ˜

Learn Django is one of my go-to resources in being a Django developer. If you havenโ€™t checked out the article about my top Django resources, you can check it here.

Model and Field Names

Models will always start with a Capital letter and will always be singular because they should only represent a single object and be using underscores and not a camelCase.

from django.db import models

class City(models.Model):
    town_name = models.CharField(max_length=50)
Enter fullscreen mode Exit fullscreen mode

Common Methods

Defining models is not easy nor should not be difficult. Next we add the __str__ and get_absolute_url() methods.

Defining the str method makes the model human-readable in the Django admin.

Defining the get_absolute_url() method tells Django how to calculate the canonical URL for the model. This method should return a string that references a view on the site. Itโ€™s also a good practice to use get_absolute_url() on the templates instead of hard-coding them.

<a href="town/{{ object.id }]}/">{{ object.town_name }}</a> # wrong

<a href="{{ object.get_absolute_url }}/">{{ object.town_name }}</a> # better

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

class City(models.Model):
    town_name = models.CharField(max_length=50)

    def __str__(self): # new
        return self.town_name

    def get_absolute_url(self):
        return reverse('town', kwargs={"town_name": self.town_name})
Enter fullscreen mode Exit fullscreen mode

Explicit Naming

Explicit is better than implicit

There are two ways to implicitly set the human-readable name for each field which Django does by automatically converting underscores to spaces. One is to use verbose_name(); if the field type is not OneToOneField, ManyToMany or ForeignKey, you can set it as the first positional argument.

from django.db import models 

class City(models.Model): 
    town_name = models.CharField(
    max_length=50,
    verbose_name='town name',
    )

    def __str__(self):
        return self.town_name 

    def get_absolute_url(self): 
        return reverse('town', kwargs={"town_name": self.town_name})
Enter fullscreen mode Exit fullscreen mode

If a model uses ForeignKey, the model will have access to a Manager that returns all instances of the first model. This model returns QuerySets which can be filtered to retrieve objects.

Example:

>>> a = City.objects.get()
Enter fullscreen mode Exit fullscreen mode
...
class Mayor(models.Model):
    first_name = models.CharField('first name', max_length=30)
    last_name = models.CharField('last name', max_length=30)
    city = models.ForeignKey(
        City,
        on_delete=models.CASCADE,
        related_name='mayors',
        related_query_name='human',
        )

    def __str__(self):
        return '%s %s' % (self.first_name, self.last_name)

    def get_absolute_url(self):
        return reverse('town_mayor', kwargs={'town_name': self.town_name})
Enter fullscreen mode Exit fullscreen mode

References

In [1]: from blog.source.models import Category 
In [2]: a = Category.objects.get(name='python') 
In [3]: print(a) python
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
waniw27038 profile image
waniw27038

Thanks for the detailed article on how to design better models in Django. These instructions really helped me improve my performance and organize my code more efficiently. Implementing Drift Boss Unblocked into my workflow is also a great way to ensure stability and maintainability for my project.