通用查询
1、公共函数:
def generic_query(model, filter_kwargs=None, order_by=None, limit=None, aggregate=None, annotate=None):
"""
通用的 Django ORM 查询函数。
:param model: Django 模型类
:param filter_kwargs: 过滤条件字典
:param order_by: 字符串或字符串列表,用于指定排序字段
:param limit: 返回结果的数量限制
:param aggregate: 聚合函数字典,例如 {'total': Sum('price')}
:param annotate: 注解字段字典,例如 {'item_count': Count('items')}
:return: 查询结果
"""
queryset = model.objects.all()
# 应用过滤条件
if filter_kwargs:
queryset = queryset.filter(**filter_kwargs)
# 应用排序
if order_by:
if isinstance(order_by, str):
order_by = [order_by]
queryset = queryset.order_by(*order_by)
# 应用聚合
if aggregate:
return queryset.aggregate(**aggregate)
# 应用注解
if annotate:
queryset = queryset.annotate(**annotate)
# 应用结果数量限制
if limit is not None:
queryset = queryset[:limit]
try:
# 尝试获取单个对象
result = queryset.get()
except (ObjectDoesNotExist, MultipleObjectsReturned):
# 如果没有找到对象或找到多个对象,则返回整个查询集
result = queryset
return result
2、示例
# 有两个模型 Book 和 Author,其中 Book 有一个外键关联到 Author
# app/model.py
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=5, decimal_places=2)
publication_date = models.DateField()
# =========================
# app/view.py
# 获取所有书籍
books = generic_query(Book)
print(books)
# 根据价格过滤书籍
cheap_books = generic_query(Book, filter_kwargs={'price__lt': 10.00})
print(cheap_books)
# 按作者名称排序书籍
sorted_books = generic_query(Book, order_by=['author__name'])
print(sorted_books)
# 获取前 5 本书
top_five_books = generic_query(Book, limit=5)
print(top_five_books)
# 计算所有书籍的平均价格
average_price = generic_query(Book, aggregate={'avg_price': Avg('price')})
print(average_price)
# 统计每个作者的书籍数量
books_per_author = generic_query(Book, annotate={'book_count': Count('author')})
print(books_per_author)
通用创建
1、公共函数:
from django.core.exceptions import ValidationError
def generic_create(model, **kwargs):
"""
通用的 Django ORM 创建函数。
:param model: Django 模型类
:param kwargs: 要创建的对象的属性值
:return: 创建的对象实例
"""
try:
# 创建并保存对象
obj = model(**kwargs)
obj.full_clean() # 验证数据是否符合模型的约束
obj.save()
return obj
except ValidationError as e:
# 处理验证错误
raise ValueError(f"Validation error: {e}")
except Exception as e:
# 处理其他异常
raise ValueError(f"An error occurred: {e}")
2、示例
# 有两个模型 Book 和 Author,其中 Book 有一个外键关联到 Author
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=5, decimal_places=2)
publication_date = models.DateField()
# =======================
# 创建一个新的作者
new_author = generic_create(Author, name="J.K. Rowling")
print(new_author)
# 创建一本新书: 先获取或创建一个关联作者, 再创建一本书
author = generic_create(Author, name="George Orwell")
new_book = generic_create(Book, title="1984", author=author, price=15.99, publication_date="1949-06-08")
print(new_book)
# 创建一本书并关联已有的作者
# 假设已经有一个作者对象
existing_author = Author.objects.get(name="J.K. Rowling")
# 创建一本书并关联已有的作者
new_book = generic_create(Book, title="Harry Potter and the Chamber of Secrets", author=existing_author, price=12.99, publication_date="1998-07-02")
print(new_book)
# 处理多对多关系:
# 一个作者并关联多本书
# 创建多个书籍对象
book1 = generic_create(Book, title="Book 1", author=existing_author, price=10.99, publication_date="2020-01-01")
book2 = generic_create(Book, title="Book 2", author=existing_author, price=11.99, publication_date="2020-02-01")
# 获取/创建一个作者并关联多本书
existing_author = Author.objects.get(name="J.K. Rowling")
existing_author.books.add(book1, book2) # 假设 Author 模型中有一个 ManyToManyField 名为 books
print(existing_author)
通用更新
def generic_update(model, filter_kwargs, update_fields):
"""
通用的 Django ORM 修改函数。
:param model: Django 模型类
:param filter_kwargs: 要修改的对象的过滤条件字典
:param update_fields: 要更新的字段及其新值的字典
:return: 修改后的对象实例
"""
try:
# 获取对象
filter_objs = model.objects.filter(**filter_kwargs)
if filter_objs:
obj = filter_objs.first()
else:
raise ObjectDoesNotExist
# 更新字段
for field, value in update_fields.items():
setattr(obj, field, value)
# 验证数据是否符合模型的约束
obj.full_clean()
# 保存对象
obj.save()
return obj
except ObjectDoesNotExist:
raise ValueError(f"Object with filter_kwargs {filter_kwargs} does not exist.")
except ValidationError as e:
# 处理验证错误
raise ValueError(f"Validation error: {e}")
except Exception as e:
# 处理其他异常
raise ValueError(f"An error occurred: {e}")
通用删除
def generic_delete(model, filter_kwargs):
"""
通用的 Django ORM 删除函数。
:param model: Django 模型类
:param filter_kwargs: 要删除的对象的字典属性值
:return: 删除的对象实例(如果成功删除)
"""
try:
# 获取对象
# 获取对象
filter_objs = model.objects.filter(**filter_kwargs)
if filter_objs:
obj = filter_objs.first()
else:
raise ObjectDoesNotExist
# 删除对象
obj.delete()
return obj
except ObjectDoesNotExist:
raise ValueError(f"Object with primary filter_kwargs {filter_kwargs} does not exist.")
except Exception as e:
# 处理其他异常
raise ValueError(f"An error occurred: {e}")
标签:generic,author,Book,数据库,django,filter,models,ORM,kwargs
From: https://www.cnblogs.com/lanjianhua/p/18549003