19.Introduction to Django Models
A model is a class that represents a table in our database. Each model is a Python class that subclasses django.db.models.Model
. Each attribute of the model represents a database field. With all of this, Django gives you an automatically-generated database-access API; see Making queries.
19.1 setting up a database
By default, Django uses SQLite as its database. SQLite is included in Python, so you won’t need to install anything else to support your database. When starting a new project, you can specify the database to use by setting the ENGINE
setting to the appropriate database backend. Here’s the full list of built-in database backends that Django supports:
django.db.backends.sqlite3
django.db.backends.postgresql
django.db.backends.mysql
django.db.backends.oracle
for example, if you want to use mysql as your database you can set the ENGINE
setting to django.db.backends.mysql
in the settings.py
file.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mydatabase',
'USER': 'mydatabase',
'PASSWORD': 'mypassword',
'HOST': '',
'PORT': '3306',
}
}
19.2 Fields
Fields are specified by class attributes. Be careful not to choose field names that conflict with the models API like clean, save, or delete.
Filed Types: Please go to Django Documentation to see the list of all field types.
19.3 Field options
null
:If null is set to True, the field will accept empty values. i.e Databse will store NULL values for this field if null=True is set and no value is provided.
name = models.CharField(max_length=100, null=True)
blank
:If blank is set to True, the field will be allowed to be blank. i.e form validation will allow entry of an empty value if blank=True is set and no value is provided
name = models.CharField(max_length=100, blank=True)
Note that this is different than null. null is purely database-related, whereas blank is validation-related. If a field has blank=True, form validation will allow entry of an empty value.
choices
:Used to set the choices for the field.
CHOICES=(('M','MALE'),('F','FEMALE'),('O','OTHER'),)
class Person(models.Model):
gender=models.CharField(max_length=1,choices=CHOICES)
default
:The default value for the field .When the model is saved and no value is provided for the field, the default value will be used.
name = models.CharField(max_length=100, default='SOME STRING')
primary_key
:If True, this field is the primary key for the model.
name = models.CharField(max_length=100, primary_key=True)
Note: If you don’t add any field specifying a primary key, Django will automatically add a primary key field with auto-increment whose name is
id
. If you add some field setting that field as primary key, it can be accessed by using.name
and.pk
as well.
unique
:If True, this field must be unique throughout the table.
name = models.CharField(max_length=100, unique=True)
-db_index
:If True, an index will be created for this field.due to which the query operation like filter,order_by will be faster.
name = models.CharField(max_length=100, db_index=True)
-editable
:If False, the field will not be displayed in the admin or any other forms.
name = models.CharField(max_length=100, editable=False)
validators
:List of validators to run for this field.We can create custom validators for the field.
from django.core.exceptions import ValidationError
def validate_even(value):
if value % 2 != 0:
raise ValidationError(
('%(value)s is not an even number'),
params={'value': value},
)
class MyModel(models.Model):
even_field = models.IntegerField(validators=[validate_even])
verbose_name
:A human-readable name for the field.
name = models.CharField(max_length=100, verbose_name='Full Name')
19.4 meta class
The Meta
class inside the model contains metadata. It is used to define metadata for the model class. Some of the metadata options are:
abstract
:If True, this model will not be used to create any database table instead it will be used as a base class for other models.for exampple:
class Animal(models.Model):
breed=models.CharField(max_length=100)
class Meta:
abstract=True
class Dog(Animal):
name=models.CharField(max_length=100)
Here Animal
model will not create any table in the database but Dog
model will create a table with fields breed
and name
.
verbose_name
:A human-readable name for the model.
class MyModel(models.Model):
class Meta:
verbose_name='My Model'
verbose_name_plural
:A human-readable plural name for the model.
class MyModel(models.Model):
class Meta:
verbose_name_plural='My Models'
ordering
:A list of field names to order the model by. It is used to specify the default ordering for the model.While querying the model, the results will be ordered by the specified fields.
class MyModel(models.Model):
class Meta:
ordering = ['name'] # Order by name field
19.5 Simple Model Example
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField(default=0)
class Meta:
verbose_name='Person'
verbose_name_plural='Persons'
class __str__(self):
return self.name
19.6 MakeMigration and Migrate
After creating the model we run
python manage.py makemigrations
:his command is used to create migrations for changes made to models. It generates a migration file in the migrations folder, which contains the necessary schema changes (e.g., creating or modifying tables) for the model.python manage.py migrate
:This command is used to apply the migrations to the database. It reads the migration files in the migrations folder and updates the database schema by creating or altering the database tables accordingly.- Use
python manage.py flush
to delete all the data in the database. - Use
python manage.py shell
to open the python shell with the Django environment. - Use
python manage.py createsuperuser
to create a superuser for the admin panel.
19.7 Using Custom Methods in Django Models
You can define custom methods in a Django model to add row-level logic. This is a valuable technique for keeping business logic centralized within the model itself, rather than scattering it across views or templates.
Instead of separating code in the view, we can use these methods directly in the model. This method is available for all objects, i.e., row-wise data, and takes the value of that object to produce the output.
Example
from django.db import models
class MyModel(models.Model):
fname = models.CharField(max_length=100)
lname = models.CharField(max_length=100)
value = models.IntegerField()
@property
def name(self):
"""Combine first and last names into a single string."""
return f"{self.fname} {self.lname}"
def custom_method(self):
"""Return a message based on the model's value."""
if self.value > 10 and self.fname.startswith('A'):
return f"{self.name} has a high value!"
else:
return f"{self.name} has a low value."
How it works
- The
name
property creates a full name fromfname
andlname
. - The
custom_method
uses the model’s data to encapsulate custom logic. - These methods are not stored in the database—they exist only for computation or presentation purposes.
- The method works row-wise for each object, allowing each instance to calculate its own output based on its values.
Usage
# Create a new instance
MyModel.objects.create(fname='John', lname='Doe', value=15)
# Retrieve the instance
instance = MyModel.objects.get(fname='John')
# Use the custom method
instance.custom_method() # Returns "John Doe has a low value."
# Use the name property
instance.name # Returns "John Doe"
This approach keeps your logic organized, reusable, and easy to maintain, especially for complex business rules.
19.8 Overriding the Save Method
Since every model inherits from django.db.models.Model
, it means it inherits from the Model class.
If you want to do some custom logic before saving the model, you can override the save method of the model.
Basic Override Example
from django.db import models
class MyModel(models.Model):
name = models.CharField(max_length=100)
def save(self, *args, **kwargs):
# Custom logic before saving
print(f"Saving {self.name}")
super().save(*args, **kwargs) # Call the original save method
Auto-generating Slug Example
from django.db import models
class MyModel(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField(max_length=100, unique=True)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = self.title.lower().replace(" ", "-") # Example slug generation
return super().save(*args, **kwargs) # Call the original save method
Conditional Save Example
from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def save(self, **kwargs):
if self.name == "Yoko Ono's blog":
return # Yoko shall never have her own blog!
else:
return super().save(**kwargs) # Call the "real" save() method.
You can similarly override the
delete()
and other model methods as needed.
19.9 Using Methods in Models (Previous Example)
To do operation related to the model we can define methods in the model class itself.
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField(default=0)
grade = models.IntegerField(default=0)
def is_adult(self):
return self.age >= 18
def is_pass(self):
return self.grade >= 40
def __str__(self):
return self.name
Now we can use these methods in views or templates:
person = Person.objects.get(id=1)
print(person.is_adult())
print(person.is_pass())