Django ORM: The most comprehensive guide to database handling

In-depth discussion of Django ORM concepts, basic usage, advanced operations, and detailed analysis of how to handle database operations in actual use. At the same time, we also discussed in-depth understanding of the model, how to perform CRUD operations, and in-depth understanding to advanced topics such as database migration. In order to fully interpret Django ORM, we also discussed its shortcomings and looked forward to its future development. This article aims to help readers get a good grasp of Django ORM, understand how it simplifies database operations, and understand its inner workings under the surface.

Introduction to Django ORM

Before discussing Django's ORM (Object-Relational Mapping, object-relational mapping) in depth, let us first understand what ORM is.

ORM is a programming technique used to create a compatible system between object-oriented software and relational databases. Simply put, ORM allows you to use Python (or other programming languages) to operate the database, just like you are operating Python objects.

Django's ORM is a very powerful tool that helps you manage and query databases. Based on the main advantages of Django ORM, you can:

  • Use Python's object model to query databases without writing complex SQL statements.
  • Achieve platform independence of the database, because Django ORM can run on a variety of database systems.

Let's illustrate this concept with a simple example. Let's say we have a model called "Blog" with a field called "title". Using the Django ORM, we can easily query for all blogs whose title contains "Django".

# 导入模型
from myapp.models import Blog

# 使用ORM进行查询
blogs = Blog.objects.filter(title__contains='Django')

# 输出查询结果
for blog in blogs:
    print(blog.title)

If you have blogs named "Learning Django" and "Django ORM basics" in your database, the above code will output:

Learning Django
Django ORM basics

Seeing this, you may find the power of Django ORM: it converts complex database operations into Python object operations, which greatly improves our programming efficiency.


Django ORM operation mechanism and model introduction

Django ORM operating mechanism

Django ORM maps classes to database tables, class instances to table records, and class fields to database columns. In this way, you can use Python code to operate on the database without writing any SQL statements.

In Django ORM, each model (model) corresponds to a database table, the fields of the model correspond to the columns of the table, and the instances of the model correspond to the rows of the table.

Introduction to Django Models

In Django, a model is a high-level abstraction over a database table. By defining a model, you can explicitly specify the structure of the database, including the names of the data tables, the names and types of fields, and possible indexes.

Let's look at a simple example, defining a model called "Blog":

from django.db import models

class Blog(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    pub_date = models.DateTimeField(auto_now_add=True)

In this example, we define a Blogmodel called , which has three fields: title, , contentand pub_date. Each field corresponds to a column type of the database: CharFieldcorresponding to the character type, TextFieldcorresponding to the text type, DateTimeFieldcorresponding to the date and time type.


In-depth understanding of Django model Model

define model

In Django, the model is the core component of the data access layer, which defines the most important behavior for your data. Model is a Python class that subclasses django.db.models.Model. Each model corresponds to a database table.

from django.db import models

class Blog(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    pub_date = models.DateTimeField(auto_now_add=True)

In the example above, we defined a Blogmodel called , which has three fields: title, , contentand pub_date.

Model field type

Django provides many built-in field types that can meet most database design needs. For example:

  • CharField: A character field, used to store shorter strings, such as titles.
  • TextField: Text fields, used to store large amounts of text, such as blog content.
  • DateTimeField: Datetime field, used to store date and time.

Each field type has its specific parameters, such as CharFieldrequiring a max_lengthparameter specifying the maximum length of the field.

Model Relationships

Django's model can also define complex association relationships, including one-to-one (OneToOne), one-to-many (ForeignKey) and many-to-many (ManyToMany) relationships.

For example, we can define a Authormodel, and associate it with Bloga model:

class Author(models.Model):
    name = models.CharField(max_length=100)

class Blog(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    pub_date = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

Here we Blogadded a authorfield to the model, which is a foreign key field ( ForeignKey), pointing to Authorthe model. This means that each blog has an author, and each author can write multiple blogs.

When we delete an author, on_delete=models.CASCADEthe parameter will ensure that all associated blogs are also deleted.


Django ORM adds, deletes, modifies, and checks CRUD operations

After understanding the Django model, let's take a look at how to use Django ORM to perform common database operations: create (Create), read (Retrieve), update (Update) and delete (Delete), often referred to as CRUD operations.

create record

In Django ORM, we can create new records by creating an instance of a model. Here is an example of creating a new Blogrecord:

from myapp.models import Blog

# 创建新的Blog实例
blog = Blog(title='My first blog', content='This is my first blog post.')
blog.save()  # don't forget to call save method

save()method will save the new Bloginstance to the database.

read record

Django ORM provides a variety of methods to read records in the database. We can use all()methods to get all records, and we can use filter()methods to get records that meet certain criteria.

from myapp.models import Blog

# 获取所有Blog记录
blogs = Blog.objects.all()

# 输出所有Blog的标题
for blog in blogs:
    print(blog.title)

If there is a blog named "My first blog", the above code will output:

My first blog

update record

Updating records in the database is also simple. We can get an instance of a record, modify its properties, and call save()methods:

from myapp.models import Blog

# 获取第一个Blog记录
blog = Blog.objects.first()

# 更新标题
blog.title = 'My updated blog'
blog.save()

This code will update the title of the first blog in the database.

Delete Record

To delete a record in the database, we can get an instance of the record and call delete()the method:

from myapp.models import Blog

# 获取第一个Blog记录
blog = Blog.objects.first()

# 删除记录
blog.delete()

This code will delete the first blog in the database.


Django ORM database advanced operation

After mastering the basic operations of Django ORM, let's take a look at some more advanced database operations, including complex queries, query optimization, etc.

complex query

In Django ORM, we can use filter(), exclude(), order_by()and other methods to perform complex queries.

For example, we can find all blogs with "django" in their title, sorted by publish date in descending order:

from myapp.models import Blog

# 获取所有标题包含'django'的Blog记录,并按照发布日期降序排序
blogs = Blog.objects.filter(title__contains='django').order_by('-pub_date')

# 输出这些Blog的标题
for blog in blogs:
    print(blog.title)

If there are blogs whose title contains 'django', the above code will print their titles in descending order of publication date.

query optimization

For large databases, optimizing queries is very important. The Django ORM provides several tools to help you optimize your queries, including select_related()and prefetch_related().

select_related()Objects associated with the ForeignKey associated with the query object can be obtained at one time, which can reduce the number of database queries:

from myapp.models import Blog

# 获取所有Blog记录,并一次性获取每个Blog的author信息
blogs = Blog.objects.select_related('author').all()

# 输出Blog的标题和作者名
for blog in blogs:
    print(blog.title, blog.author.name)

If there is a blog with author name 'John' and title "My first blog", the above code will output:

My first blog John

prefetch_related()It is also very useful for ManyToMany associations and one-to-many associations, which can obtain all related objects at one time and reduce the number of database queries.


Using Database Constraints to Ensure Data Consistency

Django ORM provides a variety of database constraints, such as uniqueand check, which can help us ensure the data consistency of the database.

# 例子:使用unique约束确保每个作者的email是唯一的
class Author(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField(unique=True)

Improve performance with batch operations

Django ORM provides bulk_createand and bulk_updateother methods that allow us to create and update batches in a more efficient manner.

# 例子:使用bulk_create方法批量创建对象
authors = [Author(name=f'Author {i}') for i in range(1000)]
Author.objects.bulk_create(authors)  # 这个操作只需要一次数据库查询

Use native SQL

Although Django ORM provides many powerful query tools, sometimes you may need to execute SQL statements directly. Django ORM allows you to execute raw SQL, you can use raw()methods or cursor()methods to execute raw SQL:

from django.db import connection

# 使用cursor()执行原生SQL
with connection.cursor() as cursor:
    cursor.execute("SELECT title FROM myapp_blog")
    row = cursor.fetchone()

print(row)

This code will directly execute the SQL query and print out the title of the first blog. Although Django ORM provides the .raw() method that allows us to directly execute SQL queries, this method should be avoided as much as possible, because it may cause security issues such as SQL injection, and it also loses many advantages of Django ORM.


Django database migration

Django's database migration system can automatically convert your changes to the model (add fields, delete models, etc.) into SQL commands and execute these commands in the database. This is a way of versioning your database, allowing you to make changes to your models and keep your database up to date.

create migration

When you make changes to your model (for example, add a field, change a field's type, etc.), you need to create a migration to apply those changes to the database. You can use makemigrationsthe command to create migrations:

python manage.py makemigrations your_app_name

The above command will check the current state of your model and database, and then create a new migration that includes everything needed to update the database to the new state.

application migration

After creating the migration, you need to migrateapply the changes to the database using the command:

python manage.py migrate

This command will perform any unapplied migrations, bringing your database up to date.

View migration status

You can showmigrationsview the status of all migrations (applied and unapplied) with the command:

python manage.py showmigrations

Executing the above command will list all migrations and their status, which can help you understand the current state of the database.

rollback migration

Occasionally, you may need to undo a migration. You can migraterollback a migration with the command and the migration name (or the migration name before the migration name):

python manage.py migrate your_app_name 0001

This command will undo the named 0002migration (and all migrations after it), and roll back the database to 0001the state of .


Disadvantages of Django ORM

Although Django ORM is a powerful and convenient tool, it is not invulnerable. Understanding these limitations can help us make more informed decisions about when and how to use it.

performance overhead

The Django ORM requires additional processing to convert database rows into Python objects. This means that using the Django ORM will generally be slower than using SQL statements directly. However, this performance overhead is usually acceptable unless you are dealing with extremely large amounts of data.

Some complex SQL queries are not supported

Although Django ORM supports many SQL features, there are some complex SQL queries that may not be possible through Django ORM's query API. For example, for specific features of certain databases or advanced SQL functions, it may be necessary to write native SQL statements.

Additional study and understanding required

Although Django ORM can help us avoid writing SQL directly, to use it effectively, we still need to understand the basic concepts of database. Moreover, Django ORM's own API and features also require some learning and understanding.

Hiding from the database can lead to misinterpretation

The Django ORM hides many details of the database, which makes programming easier, but can also lead to misunderstandings about the database operations being performed. For example, a seemingly simple operation may actually trigger multiple database queries.

# 例子:看似简单的操作实际上引发了多次数据库查询
for book in Book.objects.all():
    print(book.author.name)  # 这个操作对每本书都会引发一个数据库查询

In this example, the operation of printing the author name for each book will actually trigger a database query for each book, which will be very slow if there are a large number of books. This is because Django ORM is lazy loaded by default, that is, it will only query the database for data when it is needed.


Django ORM summary and outlook

After studying this article, we have a deep understanding of the working principle of Django ORM, implemented some basic and advanced database operations, and also understood some of its best practices and limitations.

As an important part of Python Web development, Django ORM has won the favor of many developers for its simplicity and powerful functions. Although it has some limitations, such as the support of some complex queries is not very good, and its hiding of database operations may cause performance problems, but overall, Django ORM is a very effective tool that can help us faster Better web development.

In the future, we can expect Django ORM to continue to improve, providing more features and better performance. At the same time, we can also make better use of Django ORM and improve our development efficiency through in-depth study and practice.

If it is helpful, please pay more attention to the personal WeChat public account: [Python full perspective] TeahLead_KrisChang, 10+ years of experience in the Internet and artificial intelligence industry, 10+ years of experience in technology and business team management, Tongji Software Engineering Bachelor, Fudan Engineering Management Master, Aliyun certified cloud service senior architect, head of AI product business with hundreds of millions of revenue.

Guess you like

Origin blog.csdn.net/magicyangjay111/article/details/131636018