The Meta
class in Django is used to provide additional information and configuration options for models. It allows you to customize various aspects of how a model behaves and interacts with the database.
Database Table Name:
You can specify the name of the database table for the model using the db_table
option. By default, Django generates the table name based on the app name and model name. It can be set as follows, lets create a new model for this :
class Category(models.Model):
name = models.CharField(max_length=100)
class Meta:
db_table = 'product_category_table'
After adding this model, you need to run the python manage.py makemigrations
and python manage.py migrate
command.
python manage.py makemigrations
python manage.py migrate
Now, the database table would be created with the following name, product_category_table
.
Model Ordering:
You can define a default ordering for query sets using the ordering option. This determines the order in which records are retrieved from the database when no specific ordering is requested.
class Category(models.Model):
name = models.CharField(max_length=100)
class Meta:
db_table = 'product_category_table'
ordering = ['name']
Now after this change, when retrieving values it will order it by its name by default.
from modeldemo.models import *
Category.objects.create(name='Electronics')
Category.objects.create(name='Books')
Here 2 objects are created, you can override the __str__
function to make the names human readable.
Category.objects.all()
Even though, Electronics category was added before Books, its displayed second as the ordering is given in Meta
class.
Human-Readable Names:
You can set the human-readable singular and plural names for the model using verbose_name
and verbose_name_plural
. These names are used in the Django admin interface and other places where the model's name is displayed.
class Meta:
db_table = 'product_category_table'
ordering = ['name']
verbose_name = 'Product Category'
verbose_name_plural = 'Product Categories'
Unique Constraints:
You can define unique constraints on one or more fields using the unique_together option. This ensures that combinations of field values must be unique in the database.
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
full_name = models.CharField(max_length=60, null=True)
birth_date = models.DateField()
is_active = models.BooleanField(default=True)
def __str__(self):
return f"{self.first_name} {self.last_name}"
class Meta:
unique_together = ('first_name', 'last_name')
You need to run the python manage.py makemigrations
and python manage.py migrate
command, to update the changes.
python manage.py makemigrations
python manage.py migrate
In this example, we have added unique_together
for first_name and last_name so if you try to add duplicate values for ir you will get an error.
person = Person.objects.create(first_name='ED', last_name='KOOL', birth_date='1995-01-01')
The error message would look like this :
sqlite3.IntegrityError: UNIQUE constraint failed: modeldemo_person.first_name, modeldemo_person.last_name
Indexes:
You can specify database indexes on one or more fields to improve query performance using the indexes
option.
class Post(models.Model):
author = models.ForeignKey(Person, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
content = models.TextField()
class Meta:
indexes = [
models.Index(fields=['author']),
models.Index(fields=['title']),
]
In this example, two indexes are defined:
- An index on the
author
field: This index can speed up queries that involve filtering or sorting by the author of a post. - An index on the
title
field: This index can speed up queries that involve sorting or filtering by the title of a post.
Adding these indexes can be beneficial when you expect to perform queries that filter or order your Post
objects based on these fields.
After defining these indexes, you should create and apply database migrations to update the database schema:
python manage.py makemigrations
python manage.py migrate
Keep in mind that adding indexes can improve query performance but may slightly increase the time it takes to insert or update records in the database. Therefore, it's essential to consider the specific query patterns and usage patterns of your application to determine where indexes are most beneficial.
Custom Permissions:
You can define custom permissions for the model using the permissions option. This allows you to specify permissions that can be assigned to users or groups.
class Post(models.Model):
author = models.ForeignKey(Person, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
content = models.TextField()
class Meta:
indexes = [
models.Index(fields=['author']),
models.Index(fields=['title']),
]
permissions = [
("can_view", "Can view posts"),
("can_edit", "Can edit posts"),
]
After adding the permissions you can give, python manage.py makemigrations
and python manage.py migrate
.
python manage.py makemigrations
python manage.py migrate
The first element in each tuple is the codename for the permission, and the second element is a human-readable description. You can assign custom permissions to users or groups using the Django admin interface or programmatically in your views or scripts. Custom permissions offer fine-grained control over access to specific actions or resources within your Django application, allowing you to tailor access rights to your application's requirements.