One of the principles of Python is “Do not repeat yourself”. Abstract models in Django are meant to do exactly that.
If you are designing a database for a school, there would be database models representing all types of people who attend this school which includes the students, teachers, cleaning staff, cafeteria staff, school bus drivers, etc.
However, all of these folks have some common information such as name, date of birth, date of joining, address and contact information, etc.
It doesn't seem right to repeat all of these fields for each database model while writing the code, and this is where abstract models work great.
All you have to do is create a base model with all the common fields and set abstract = True in the meta class.
This will ensure that there is no actual database table created for this base model and it is meant only for being inherited by other models that actually become tables in the database.
After running migrations, there will be a student table and a teacher table created in your database while the person model stays in your codebase ready to be inherited in another model if you chose to.
The “Do not repeat yourself” principle does not have to end here. For instance, even though the folks belonging to the cleaning staff and cafeteria staff are also persons, they both have shift timings which students and teachers do not.
Depending on your requirement you can have further abstract models that inherit from other abstract models.
It is important to keep in mind that abstract models by themselves are quite useless. There is no database table created for them and hence they are of no consequence.
Abstract models are only useful if you intend to create other models which inherit from the abstract ones.
Abstract classes are a good example of how the concept of inheritance can be used to write reusable code.