Sometimes we want to change how our data is stored or how we can access the table. Generally, Django ORM does the heavy lifting, including building tables, naming fields, and data ordering. In Django, we can communicate a database with additional parameters while storing data. This can be done using the optional Meta class.
The meta class
In Django, we can create a metadata class that provides additional information about the Model class we have created before. The metadata of the Model class is anything that is not a field. They may include ordering options, naming a database table, giving singular and plural names to the models, and so on. Django provides us with 25 available meta options; two are read-only. Here, we will talk about a few of the most frequently-used Meta options. You can find more about them in the official Django documentation.
The meta class is the inner class of a model. It defines the selected model class. For example, we can compose a model as follows:
from django.db import models
class Player(models.Model):
name = models.CharField(max_length=250)This is our typical model. The model class defines a Player that has a name field. We can add the meta class as:
from django.db import models
class Player(models.Model):
name = models.CharField(max_length=250)
class Meta:
ordering = ["name"]
verbose_name_plural = "players"We've added the meta class to the player model. Generally, objects are ordered based on their id. Here, we've overridden the ordering option. Now, our model is ordered alphabetically. The verbose_name_plural is added to get a plural name for the object. There is a similar option called verbose_name. These two options give an ordinary-language name for a model. We will brief you on this later.
Additional meta options
In this section, we will glance through additional options of the meta class.
Django can automatically derive the database table name from the name of our model class and the app that contains it. A model’s database table name is constructed by joining the model’s app name and the model’s class name with an underscore in between. Suppose we have the car model inside an app named Vehicle. In this case, the table name is going to be vehicle_car. The CamelCase class name is replaced as camel_case:
class Car:
...
...
class Meta:
db_table = 'car'
By defining db_table, we can name the table as we want, given the details above.
Sometimes while writing a model class, we may define it outside of the app listed under INSTALLED_APPS in the settings. In this case, we must declare the model in the app where it belongs. This can be done by adding the app_label option in the meta class.
Suppose we have defined the car class used in the previous example in some other app. We must define app_label as:
class Car:
...
...
class Meta:
app_label = 'my_app'Another additional parameter that can be included in the meta class is verbose_name. It provides an everyday-language readable name for the model we define. If our model is CamelCase, it will be converted as Camel Case. This option works most of the time when you want to name the model in a more descriptive or human-readable way. For this, refer to verbose_name:
class AboutCars:
...
...
class Meta:
verbose_name = 'Car'The model name was changed to just Car instead of About Cars.
Verbose_name_plural has functionality similar to verbose_name. It gives an ordinary-language plural form to the model we've defined. We have defined a model class Child and have registered it in admin.py. If we open our admin panel, we can see the model as Childs. This is the result provided by Django. If verbose_name_plural is not defined, Django, by default, puts it as verbose_name + s. Since Childs is not correct, we can change it by passing the correct plural name in verbose_name_plural:
class Child:
...
...
class Meta:
verbose_name = 'child'
verbose_name_plural = 'children'After adding verbose_name_plural, we can take another look at our admin page — Childs model is now Children; the data inside remain unchanged.
Sometimes, we need to provide additional permissions to certain users and objects. We can change the permissions option. Permissions to add, change, delete, and view are automatically created for each model:
class Adult:
...
...
class Meta:
permissions = [('can_work', 'Can work')]This permission option provides the model object Adult with the external permission can_work that has been defined in the project. The permission option is a list of tuple-pairs in the format: permission_code, human_readable_permission_name.
The default ordering of the objects in the database is usually alphabetical. We can change it by overriding the ordering option in the meta class.
class Adult:
...
...
order_date = models.DateField()
class Meta:
ordering = ['-order_date']This option is a tuple or list of strings and/or query expressions. Each string is a field name with the optional - prefix that indicates descending order. Fields without the leading - will be ordered ascendingly. You can also use ? for random ordering.
For example, to order by an order_date field in ascending order, use this:
ordering = ['order_date']To order by name in descending order:
ordering = ['-author']We can order an object based on any field.
Conclusion
The meta class communicates and alters a database with the help of meta options without actually writing a query. Meta options are safe, as they do not change data in the database. Meta options are plentiful. It's worth trying them all! In this topic, we have discussed the following options:
db_tablesets a database table name;app_labelsets an app label;verbose_nameoutputs an ordinary-language name of a model;verbose_name_pluralprovides a plural name of a model;permissionsprovides permissions to model objects;orderingorders model objects.