开启智能数字体验
Djacore CMS 驱动未来

基于Django 5.2的企业级智能内容管理系统,为千万级数据量设计, 提供安全、高效、可扩展的网站建设与内容管理一体化解决方案

django 批量操作的方法有哪些?如何高效的批量更新django内容

:本站 2025-10-31 23:30:10 16

django 批量操作的方法有哪些?如何高效的批量更新django内容

Django 提供了多种批量操作方法,能显著提升数据库操作的效率,特别是在处理大量数据时。下面为你梳理这些方法,并说明其适用场景和注意事项。

下表总结了主要的批量操作方法及其核心用途:

方法类别

核心方法

主要用途

关键特点

📦 批量创建

bulk_create()

一次性创建大量对象

将多个 INSERT语句合并为一个,极大提升创建速度

 

🔄 批量更新

update()

为查询集中的所有对象设置相同的字段值

在数据库层面单条**L完成更新,不触发模型的 save()方法

 

 

bulk_update()

一次性更新多个对象的不同字段值

适用于需要分别修改多个对象的不同属性,比循环调用 save()更高效

 

🗑️ 批量删除

delete()

一次性删除查询集中的所有对象

高效的物理删除

 

🔗 多对多关系

add()/ remove()

一次性添加或移除多个多对多关联

减少操作关联表的**L查询次数

 

详细方法与使用场景

📦 批量创建对象

使用 bulk_create()是创建大量对象时的首选方法。

基本用法:创建一个对象列表,然后传入 bulk_create()方法。

from myapp.models import Book

books = [
    Book(title='Book 1', author='Author 1'),
    Book(title='Book 2', author='Author 2'),
    # ... 可以继续添加更多对象
]
Book.objects.bulk_create(books)

处理海量数据:如果需要创建的对象数量极大(例如上万条),建议使用 batch_size参数进行分批提交,以避免单个数据库事务过大。batch_size参数可以控制每批处理的数据量。

# 方法一:在 bulk_create 中直接指定 batch_size
Book.objects.bulk_create(book_list, batch_size=1000)

# 方法二:手动分批次处理
batch_size = 1000
for i in range(0, len(book_list), batch_size):
    batch = book_list[i:i+batch_size]
    Book.objects.bulk_create(batch)

🔄 批量更新对象

根据更新需求的不同,可以选择两种方法。

  • 使用 update()进行统一更新

    当需要将符合条件的所有记录的某个字段设置为同一个值时,使用 update()效率最高。

    # 将所有状态为“pending”的书籍状态更新为“approved”
    Book.objects.filter(status='pending').update(status='approved')

    此方法不会调用模型的 save()方法,因此不会触发相关的信号(如 pre_save, post_save)。

  • 使用 bulk_update()进行批量差异更新

    当需要更新的多个对象,其字段值各不相同时,应使用 bulk_update()

    books = Book.objects.filter(status='pending')
    for book in books:
        # 对每个对象进行不同的修改
        book.price *= 1.1  # 每本书涨价10%
    
    # 批量更新,指定需要更新的字段
    Book.objects.bulk_update(books, ['price'])

     

     
     

     

🗑️ 批量删除对象

使用 delete()方法可以快速删除符合条件的所有记录。

# 删除所有已下架的商品
Product.objects.filter(is_active=False).delete()
 
 

注意:此操作是物理删除,数据将从数据库中永久移除,操作前请务必确认。

🔗 多对多关系的批量操作

对于多对多字段,也可以进行批量操作以减少**L查询次数。

  • 批量添加关联:使用 add()方法并传入多个对象。

    my_band = Band.objects.get(id=1)
    member1 = Artist.objects.get(id=2)
    member2 = Artist.objects.get(id=3)
    my_band.members.add(member1, member2)  # 一次添加多个成员
  • 批量移除关联:使用 remove()方法并传入多个对象。

    my_band.members.remove(member1, member2)  # 一次移除多个成员
 
 

💡 重要注意事项

  1. 性能权衡bulk_createbulk_update虽然性能卓越,但不会触发Django模型的 save()delete()方法相关的信号(如 pre_save, post_save等),也不会自动更新具有 auto_now属性的字段(如 DateTimeField(auto_now=True))。

  2. 返回值bulk_create方法在大多数数据库后端不会返回创建对象的主键ID,update()方法返回受影响的行数,而 delete()方法返回一个表示被删除对象数量的元组。

  3. 事务处理:对于非常重要的批量操作,建议将其放在 transaction.atomic()装饰器或上下文管理器中,以确保操作的原子性(要么全部成功,要么全部失败)。

希望这份总结能帮助你更好地运用Django的批量操作功能。

下面我们整理了一个批量更新的代码片段来说明一个批量更新的灵活运用方法

# 准备文章数据
            article_data = {
                'title':
                row_dict['log_Title'],
                'meta_keywords':
                meta_keywords.rstrip(','),
                'meta_description':
                strip_tags(row_dict['log_Intro']),
                'content':
                row_dict['log_Content'],
                'create_time':
                timezone.datetime.fromtimestamp(int(
                    row_dict['log_CreateTime'])),
                'update_time':
                timezone.datetime.fromtimestamp(int(
                    row_dict['log_UpdateTime'])),
                'hits':
                row_dict['log_ViewNums'],
                'status':
                99 if row_dict['log_Status'] == 0 else 0,
                'category':
                category_obj,
                'editor_id':
                userid
            } 
            if keep_id_c***istent:
                # 保持ID一致的逻辑
                if article_id in existing_article_ids:
                    articles_to_update.append((article_id, article_data))
                else:
                    article = Article(id=article_id, **article_data)
                    articles_to_create.append(article)
            else:
                # 不保持ID一致:不传入id,创建新记录并使用新ID
                article = Article(**article_data)  # 注意:这里没有传递 id
                articles_to_create.append(article)

        # 6. 批量数据库操作
        with transaction.atomic():
            # 批量创建新文章
            if articles_to_create:
                Article.objects.bulk_create(articles_to_create, batch_size=100)

            # 批量更新现有文章
            if articles_to_update:
                update_batch = []
                for article_id, article_data in articles_to_update:
                    article = Article(id=article_id, **article_data)
                    update_batch.append(article)

                # 指定要更新的字段
                update_fields = [
                    'title', 'meta_keywords', 'meta_description', 'content',
                    'create_time', 'update_time', 'hits', 'status',
                    'category_id', 'editor_id'
                ]
                Article.objects.bulk_update(update_batch,
                                            update_fields,
                                            batch_size=100)

💡 理解 bulk_update 的核心价值

bulk_update是 Django 用于高效批量更新大量已存在模型实例的方法。与循环遍历每个对象并调用 save()方法相比,它能将多次数据库查询合并为少数几次,从而极大地提升性能。在您处理从旧系统导入数据这类任务时,使用它是非常正确的选择。

📝 数据准备与字段映射

您的代码核心是准备一个包含更新数据的字典 article_data,并将其字段映射到 Article模型的对应字段。下表详细解析了这些映射和数据处理逻辑:

模型字段 (Article)

数据来源 (row_dict)

数据处理逻辑说明

title

log_Title

直接映射文章标题。

meta_keywords

meta_keywords(外部变量)

移除了字符串末尾的逗号。

meta_description

log_Intro

使用 strip_tags移除了可能存在的 HTML 标签,确保为纯文本。

content

log_Content

直接映射文章正文内容。

create_time

log_CreateTime

将时间戳整数转换为 Django 的时区感知日期时间对象。

update_time

log_UpdateTime

同上,记录最后更新时间。

hits

log_ViewNums

直接映射文章浏览量。

status

log_Status

进行了状态码转换(例如,原系统 0 对应新系统 99,表示发布状态)。

category

category_obj(先前查询获得)

传入已获取的分类对象,Django 会自动处理其关联的 ID。

editor_id

userid

直接映射编辑的用户 ID。

🔧 使用 bulk_update 执行批量更新

准备好数据后,使用 bulk_update进行批量更新。

  1. 构建对象列表:遍历 articles_to_update列表,为每个 (article_id, article_data)元组,使用 Article(id=article_id, **article_data)创建一个临时的、未保存的 Article实例。关键点在于必须指定 id=article_id,这样 Django 才知道要更新哪条现有记录,而不是创建新记录。

  2. 明确更新字段:在 update_fields参数中明确列出所有需要更新的字段。这是一个好习惯,可以避免意外覆盖其他字段,并且在模型字段很多时能略微提升性能。

  3. 设置批量大小:使用 batch_size参数(您设置为 100)非常重要。当需要更新的对象数量极大时(例如上万),此参数会将操作分批提交,防止单个数据库事务过大,有助于减轻数据库压力并保证稳定性。

⚠️ 重要注意事项

在使用这个高效方法时,有几个关键点需要牢记:

  • 不触发信号和模型保存方法bulk_updateupdate()方法一样,为了效率直接生成 **L 语句操作数据库,不会调用每个模型的 save()方法,因此与 save()方法相关的逻辑(如自动更新 auto_now字段)以及 pre_savepost_save信号都不会被触发。如果您的业务逻辑依赖这些,则需要考虑替代方案,如循环调用 save()或在 bulk_update前后手动执行相关逻辑。

  • 事务保障:对于重要的数据迁移或更新操作,建议将整个 bulk_update操作包裹在 transaction.atomic()装饰器或上下文管理器中,以确保操作的原子性(要么全部成功,要么全部回滚)。

希望这份详细的梳理能帮助您更好地理解和运用 bulk_update方法。

 

 

本文编辑:admin

更多文章:


使用DRF快速搭建API接口,Django REST Framework ModelViewSet 用法总结

使用DRF快速搭建API接口,Django REST Framework ModelViewSet 用法总结

Django REST Framework ModelViewSet 用法总结1. ModelViewSet 简介ModelViewSet是 Django REST Framework (DRF) 中的一个视图集类,它继承自多个 mixin

2026年3月1日 09:10

django 使用selenium注意事项:Service /usr/local/bin/chromedriver unexpectedly exited. Status code was: 1解决办法

django 使用selenium注意事项:Service /usr/local/bin/chromedriver unexpectedly exited. Status code was: 1解决办法

在实操当中有一项目需要使用selenium进行浏览器模拟,但是测试了很多都不行,最后通过了,总一下系统级安装chrome浏览器及驱动这些都不细说了测试项目运行用户:check_user.py建立一个API,使用check_user获取用户,

2026年1月6日 00:58

Django移除模型后的content_type操作

Django移除模型后的content_type操作

旧应用(apps.content.download)的模型虽然已删除,但其在 django_content_type表中的记录仍然存在,与新应用(user_space.apps.download)的记录产生了混淆。您需要清理这些过时的记录。

2025年12月22日 11:36

django.utils中都有哪些功能?django.utils工具都详情的举例说明

django.utils中都有哪些功能?django.utils工具都详情的举例说明

Django 的 django.utils模块是一个“百宝箱”,它提供了大量用于处理日常底层任务的实用工具。下面这个表格汇总了其中一些最常用的工具模块及其核心功能,可以帮助你快速了解其概貌。模块/工具类别主要功能/工具举例简要说明djang

2025年11月27日 22:32

Django 的基于类的视图总结,Django CBV类的详细使用方法整理

Django 的基于类的视图总结,Django CBV类的详细使用方法整理

Django 的基于类的视图(Class-based Views,简称 CBV)通过类的形式封装了常见的 Web 开发模式,提供了清晰的结构和强大的可复用性。下面这个表格汇总了这些核心基类的主要作用和典型应用场景,可以帮助你快速了解其用途。

2025年11月17日 08:52

Django transaction.atomic() 的具体作用和用法?

Django transaction.atomic() 的具体作用和用法?

transaction.atomic()是 Django 中用于管理数据库事务的核心工具,它能确保一系列数据库操作作为一个不可分割的“原子”单元来执行。下面这个表格能帮你快速抓住要点。特性说明核心目标保证一系列数据库操作的原子性(Atomi

2025年10月31日 23:35

django 批量操作的方法有哪些?如何高效的批量更新django内容

django 批量操作的方法有哪些?如何高效的批量更新django内容

Django 提供了多种批量操作方法,能显著提升数据库操作的效率,特别是在处理大量数据时。下面为你梳理这些方法,并说明其适用场景和注意事项。下表总结了主要的批量操作方法及其核心用途:方法类别核心方法主要用途关键特点📦 批量创建bulk_cr

2025年10月31日 23:30

django的分页器以及django分页器中有哪些变量

django的分页器以及django分页器中有哪些变量

Django 的分页器(Paginator)是一个用于管理数据分页的强大工具,它能将大量数据分割成多个页面,并生成相应的导航链接。下面这个表格汇总了 Django 分页器中的核心类及其主要属性和方法,方便你快速了解其构成。组件/类别名称说明

2025年10月20日 10:16

Django get_FOO_display() 方法,Django模型中原生方法总结

Django get_FOO_display() 方法,Django模型中原生方法总结

在Django中有一种方法被称为 ​​get_FOO_display() 方法​​,对模型中定义了 choices选项的字段名的灵活使用方法。在Django中,choices参数用于为模型字段提供一组固定的可选值,它在数据库层面存储简洁的值

2025年10月13日 20:56

django​​字段查找(Field Lookups)总结,django​​查询中指定特定的条件或对字段的处理方法

django​​字段查找(Field Lookups)总结,django​​查询中指定特定的条件或对字段的处理方法

在Django ORM中,双下划线 __后跟的关键词(如 __date、__icontains)被称为​​字段查找(Field Lookups)​​。它们用于在查询中指定特定的条件或对字段进行某种处理。 📊

2025年10月8日 23:07

最近更新

使用DRF快速搭建API接口,Django REST Framework ModelViewSet 用法总结
2026-03-01 09:10:09 浏览:4
宝塔Nginx免费防火墙常用UA防护正则
2026-01-20 00:53:21 浏览:38
django 使用selenium注意事项:Service /usr/local/bin/chromedriver unexpectedly exited. Status code was: 1解决办法
2026-01-06 00:58:37 浏览:10
Django移除模型后的content_type操作
2025-12-22 11:36:29 浏览:6
热门文章

DjancoreCMS打包前操作
2025-05-26 17:58:05 浏览:81
宝塔Nginx免费防火墙常用UA防护正则
2026-01-20 00:53:21 浏览:38
标签列表