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)
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})
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})
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()
...
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})
References
- Coding style | Django documentation | Django
- Django Best Practices: Models | LearnDjango
- Model instance reference | Django documentation | Django
- PEP 20 -- The Zen of Python | Python.org
- Making queries | Django documentation | Django
In [1]: from blog.source.models import Category
In [2]: a = Category.objects.get(name='python')
In [3]: print(a) python
Top comments (0)