Let's look at a few key points to remember while defining a
I plan to write a couple of posts regarding model design, rather than one single long post.
Models in Django
model in the Django ORM world is the equivalent of a table in the database. That's the beauty of ORMs. We can define the complete table structure in the application itself, create, modify, query and do every single thing that we do using SQLs but without them.
Let's jump in straight 😀. To not repeat myself I'd urge you to refer to my previous post to perform the usual steps of creating a Django project and other steps.
I'm a big fan of popsicles and soft cones 🍦😋. Just to give the post a bit of flavor, I decided to take an example of defining a few
models for a hypothetical website that sells and delivers ice cream.
A few models for our ice cream website would be:
Now for a few tips to keep in mind while we define a model. We shall apply them in the end to these models to see what it looks like.
Tips to remember while defining a model
Use descriptive field names
This may seem like an age-old tip. But it is forgotten many a time 😂. Do not worry about the name of a field being long as long as it is self-explanatory.
# WRONG class Customer(models.Model): fname = models.CharField(...) lname = models.CharField(...) # RIGHT class Customer(models.Model): first_name = models.CharField(...) last_name = models.CharField(...)
Use descriptive related names
Tables being related is extremely common in any database. In Django, while we use
ForeignKey as field type, make sure to give an understandable value for
If not followed from the beginning, it becomes unnecessarily complicated when the number of models starts to grow. I generally use the approach of noun + verb combination. Feel free to use whatever suits your naming standards but make sure it's descriptive. Let's see an example.
# WRONG class Order(models.Model): ordered_by = models.ForeignKey( Customer, on_delete=models.CASCADE, related_name="ordered_by") # RIGHT class Order(models.Model): ordered_by = models.ForeignKey( Customer, on_delete=models.CASCADE, related_name="customer_who_ordered")
choices whenever there is a list of values
When a field in a model is designed to have a limited set of choices (think of a dropdown as its corresponding widget in the UI), it's always a good idea to define choices for the field.
It makes the code more readable and easy to maintain when there is a need to modify the values for some business reason. Validation of the field is also quite straightforward when defined as a choice field.
Where to place the choices field is debatable 😀.
If there are a lot of such list values in your business scenario or if a particular type of value will appear in multiple tables/classes (example: gender field) then a probable case may be to have a separate
choices.py so that a particular choice field can be reused.
Otherwise, it's a good idea to just define it as the first thing in your class.
# WRONG class Icecream(models.Model): flavor = models.CharField("Choose your flavor", max_length=500, \ blank=False, null=False) # RIGHT class Icecream(models.Model): flavor_choices = ( ("butterscotch", "Butterscotch"), ("carmel", "Carmel"), ("pista", "Pista"), ("strawberry", "Strawberry"), ("vanilla", "Vanilla") ) flavor = models.CharField("Choose your flavor", choices=flavor_choices, default="vanilla")
Use indexes for frequently queried fields
There are a few fields that will be used in most of the queries, especially the unique fields in a table. For such cases, it helps by defining them as indexes as part of
Let's assume in our ice cream shop website, email is the unique identifier for a customer. Hence all queries that fetch customer details, dashboard-related ones especially will use email as part of the
where clause. In such a case, we should define the index on the
# WRONG class Customer(models.Model): first_name = models.CharField("First name", ...) last_name = models.CharField("Last name", ...) email = models.EmailField("Email address", ...) # RIGHT class Customer(models.Model): first_name = models.CharField("First name", ...) last_name = models.CharField("Last name", ...) email = models.EmailField("Email address", ...) class Meta: indexes = [ models.Index(fields=["email"]), ]
Will be continued
As I mentioned at the beginning of the post, I shall write a couple of posts in the immediate future concerning
models as it is the backbone of any Django application.
Hope you found them useful!