如何通过Django ORM编程式增创数据、用字符串指定Model字段名及场景化操作?
嘿,我来帮你梳理下Django ORM里的这些操作,都是日常开发中常用的技巧,往下看:
1. 最基础:创建Model实例后调用save()
这是最直观的方式,先构造模型实例,再手动保存到数据库。假设我们有一个Book模型,包含title、author、publish_date字段:
from myapp.models import Book # 构造实例 new_book = Book(title="Django实战指南", author="张三", publish_date="2024-01-01") # 写入数据库 new_book.save()
小提示:save()方法会自动判断是新增数据还是更新已有数据——如果实例已经有主键值,就会执行更新操作。
2. 一步到位:使用create()方法
省去手动调用save()的步骤,直接创建并保存实例,还会返回刚创建的对象:
book = Book.objects.create(title="Python进阶教程", author="李四", publish_date="2024-02-01")
3. 批量创建:bulk_create()(高效插入多条数据)
如果要一次性插入大量数据,用这个方法比循环调用create()效率高得多(减少数据库连接次数):
books_batch = [ Book(title="Flask入门", author="王五"), Book(title="FastAPI实战", author="赵六") ] Book.objects.bulk_create(books_batch)
⚠️ 注意:bulk_create()不会触发模型的save()信号,而且在部分数据库(比如MySQL)中,返回的实例主键值可能不准确,需要额外处理。
4. 避免重复:get_or_create()
适合需要确保数据唯一性的场景——先根据条件查找,不存在就创建,返回值是(实例, 是否创建成功)的元组:
book, created = Book.objects.get_or_create( title="Django实战指南", # 唯一查找条件 defaults={"author": "张三", "publish_date": "2024-01-01"} # 不存在时的字段值 ) # created是布尔值:True表示刚创建,False表示数据已存在
开发中经常遇到动态字段的需求(比如前端传字段名、批量处理不同字段),这时候可以用字符串来操作:
1. 创建实例时用字典解包
把字段名(字符串)和对应值放到字典里,用**解包传递给模型构造函数或create():
field_data = { "title": "数据分析入门", "author": "钱七", "publish_date": "2024-03-01" } # 方式一:构造实例后save new_book = Book(**field_data) new_book.save() # 方式二:直接用create Book.objects.create(**field_data)
2. 修改已有实例的字段
用Python内置的setattr()函数,通过字符串指定字段名来修改值:
book = Book.objects.get(title="Django实战指南") # 动态修改author字段 setattr(book, "author", "张大三") book.save()
3. 查询时动态指定字段
比如动态选择要返回的字段,或者动态设置过滤条件:
# 动态选择查询字段 fields_to_fetch = ["title", "author"] # 返回字典列表 books_dict = Book.objects.values(*fields_to_fetch) # 返回元组列表 books_tuple = Book.objects.values_list(*fields_to_fetch) # 动态设置过滤条件 filter_field = "author" filter_value = "张三" books = Book.objects.filter(**{filter_field: filter_value})
1. 批量更新动态字段
比如要把某个作者的所有书籍的publish_date统一更新,字段名是动态传入的:
update_field = "publish_date" update_value = "2024-04-01" Book.objects.filter(author="张三").update(**{update_field: update_value})
2. 动态创建不同Model的实例
如果需要根据字符串指定的模型名来创建实例,可以用Django的apps模块:
from django.apps import apps # 传入app名称和模型名称(都是字符串) model_class = apps.get_model(app_label="myapp", model_name="Book") # 创建实例 new_book = model_class.objects.create(title="动态创建的书籍", author="孙八")
3. 动态处理外键字段
如果模型有外键,也可以用字符串指定字段名——直接传外键实例,或者用外键字段名_id传主键ID:
from myapp.models import Category # 先获取分类实例 fiction_cat = Category.objects.get(name="小说") # 方式一:直接传外键实例 field_data = { "title": "科幻世界", "author": "周九", "category": fiction_cat } Book.objects.create(**field_data) # 方式二:用外键字段的_id后缀传ID field_data_with_id = { "title": "武侠传奇", "author": "吴十", "category_id": 1 # category是外键字段,category_id对应数据库中的字段名 } Book.objects.create(**field_data_with_id)
内容的提问来源于stack exchange,提问作者smallbee

