首页 > 数据库 >django 数据库ORM通用的公共函数

django 数据库ORM通用的公共函数

时间:2024-11-16 09:29:42浏览次数:1  
标签:generic author Book 数据库 django filter models ORM kwargs

通用查询

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

相关文章

  • 大数据-224 离线数仓 - 数仓 技术选型 版本选型 系统逻辑架构 数据库命名规范
    点一下关注吧!!!非常感谢!!持续更新!!!目前已经更新到了:Hadoop(已更完)HDFS(已更完)MapReduce(已更完)Hive(已更完)Flume(已更完)Sqoop(已更完)Zookeeper(已更完)HBase(已更完)Redis(已更完)Kafka(已更完)Spark(已更完)Flink(已更完)ClickHouse(已更完)Kudu(已更完)Druid(已更完)Kylin(已更完)Elasticsearch(已更完......
  • MiniShopping-mysql数据库
    CREATEDATABASEMiniShopping;USEMiniShopping;CREATETABLEadministrators(idINTUNSIGNEDPRIMARYKEYAUTO_INCREMENTCOMMENT'ID',passwordVARCHAR(256)COMMENT'密码',create_timeDATETIMENOTNULLCOMMENT'创建时间',update_tim......
  • 基于C#开源、功能强大、灵活的跨平台开发框架 - Uno Platform
    前言今天大姚给大家分享一个基于C#开源、功能强大、灵活的跨平台开发框架:UnoPlatform。通过UnoPlatform,开发者可以利用单一代码库实现多平台兼容,极大地提高了开发效率和代码复用性。项目介绍UnoPlatform是一个基于C#开源、功能强大、灵活的跨平台开发框架,用于快速构建单一......
  • 基于大数据 Python 歌曲筛选爬虫数据分析可视化系统(源码+LW+部署讲解+数据库+ppt)
    !!!!!!!!!选题不知道怎么选不清楚自己适合做哪块内容都可以免费来问我避免后期給自己答辩找麻烦增加难度(部分学校只有一次答辩机会没弄好就延迟毕业了)会持续一直更新下去有问必答一键收藏关注不迷路源码获取:https://pan.baidu.com/s/1aRpOv3f2sdtVYOogQjb8jg?pwd=jf1d提取码:......
  • 基于python+django的Spark的国漫推荐系统的设计与实现
    前言基于python+django的Spark国漫推荐系统能为国漫爱好者提供精准的内容推荐。系统先收集大量国漫数据,包括国漫名称、类型、作者、制作公司、评分、播放量、剧情简介、人物设定等信息。利用Spark的分布式计算能力对这些数据进行处理和存储。在用户方面,当新用......
  • 基于python+django的Hadoop的短视频数据分析的设计与实现
    前言基于python+django的Hadoop短视频数据分析系统可充分挖掘短视频数据价值。从各大短视频平台接口等多种数据源采集数据,利用Hadoop分布式存储海量短视频的基本信息、用户信息、播放量、点赞数、评论内容等。借助python数据分析库和django框架,清洗、预处理......
  • Django SQL 查询优化方案:性能与可读性分析
    DjangoSQL查询优化方案:性能与可读性分析目录⚙️使用DjangoORM的raw()方法进行SQL查询......
  • 高效Django随机查询优化方案
    高效的Django随机查询优化方案目录......
  • SpringBoot影视资源管理系统1i9zh--程序+源码+数据库+调试部署+开发环境
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、项目背景与意义随着影视行业的快速发展,影视资源的数量呈现爆炸式增长。为了更好地管理、分类和检索这些资源,我们计划开发一套影视资源管理系统......
  • MyBatis面试题--(与数据库连接的相关知识)
    目录在MyBatis中,Mapper接口的作用是什么?当实体类中属性名和表中的字段名不一样,怎么办?1.使用@Result注解2.使用resultMap元素3.使用@Results注解(MyBatis3.4.1+)4.使用mapUnderscoreToCamelCase属性在MyBatis中如何实现分页功能?1.使用MyBatis分页插件2.手动编写分页SQL3.使......