Django ORM实战:模型字段与元选项配置,以及链式过滤与QF查询详解

在这里插入图片描述

系列文章目录

  • Django入门全攻略:从零搭建你的第一个Web项目
  • Django ORM入门指南:从概念到实践,掌握模型创建、迁移与视图操作
  • Django ORM实战:模型字段与元选项配置,以及链式过滤与QF查询详解
  • 还在写0.0…

文章目录

  • 系列文章目录
  • 前言
  • 一、模型类字段
    • 1.BooleanField
    • 2.CharField
    • 3.DateField
    • 4.DatetimeField
    • 5.DecimalField
    • 6.FloatField
    • 7.IntegerField
  • 二、字段属性
    • 1.null
    • 2.blank
    • 3.choices
    • 4.db_column
    • 5.db_index
    • 6.default
    • 7.primary_key
    • 8.unique
    • 9.verbose_name
  • 三、模型类元选项
    • 1.abstract
    • 2.app_label
    • 3.abstract
    • 4.db_table
    • 5.ordering
    • 6.verbose_name
    • 7.verbose_name_plural
    • 8.ordering
  • 四、ORM增删改查
    • 0.ORM的增删改查
    • 1.增加数据
    • 2.查找对象
      • 查询中用到的一些字段:
        • a.order_by(*field)
        • b.count()
        • c.order_by(*field)
        • d.values(*fields)
    • 3.链式过滤条件
      • contains:
      • icontains:
      • range:
      • in:
      • exact:
      • iexact:
      • startswith、endswith:
      • istartswith、iendswith:
      • gte:
      • lte:
    • 4.修改对象
    • 5.删除对象
    • 6.ORM的Q、F查询
      • Q查询:
      • F查询:
    • 7.QuerySet


前言

    在Django框架中,数据是应用的核心。其强大的ORM(对象关系映射)系统使得数据操作变得直观且高效。本文将带您领略Django ORM的精髓,包括模型类字段与属性的设定、元选项的配置、以及增删改查等基础操作。特别地,我们将聚焦链式过滤条件和QF查询,让您轻松构建复杂查询。同时,深入介绍QuerySet,这个ORM的核心组件,带您领略其强大的数据处理能力。


提示:以下是本篇文章正文内容,下面案例可供参考

一、模型类字段

每一个字段都是Field基类的一个实例(Field类用来建立字段与数据库之间的映射)

1.BooleanField

True/False 字段,默认值为 None

BooleanField(**options)

2.CharField

字符串字段

CharField(max_length=None)
# max_length 设置最大的字符数长度限制

3.DateField

datetime.date实例表示的日期 2013-08-01

DateField(auto_now=False, auto_now_add=False,**options)
'''
auto_now: 该值为 True 时,每次在保存数据对象时,自动设置该字段为当前时间,也可以理解为自动更新最后一次修改时间
auto_now_add: 该值为 True 时,该字段设置在第一次数据对象创建时,可以记录当前字段创建的时间值
'''

注意:避免矛盾,auto_nowauto_now_adddefault不能同时出现,一个字段属性只能有其中一条设置,当设置了auto_now,或auto_now_add时,也会让该字段默认具有blank=True(字段可以为空)属性

4.DatetimeField

datetime.datetime实例表示的日期和时间

DatetimeField(auto_now=False, auto_now_add=False,**options)
# auto_now_add: 创时使用当前时间 注册时间
# auto_now: 修改时自动更新为当前时间 用户上次登陆,修改ip
# 和 DateField 具有相同的字段属性

5.DecimalField

Decimal实例表示的十进制浮点数类型

DecimalField(max_digits=None,decimal_places=None, **options)
'''
max_digits: 位数总数,包括小数点后的位数,必须大于 decimal_places 参数
decimal_places: 小数点后的数字数量,精度
'''

6.FloatField

使用float实例来表示的浮点数

FloatField(**options)

7.IntegerField

一个整数,范围由-21474836482147483647

IntegerField(**options)

二、字段属性

1.null

如果该值为True,将在数据库中将控制存储为NULL

# app/models.py下的模型类中
title = models.CharField(max_length=100,null=True)
# 允许title为空

2.blank

如果该值为True,则在验证时该字段值可以为空

null为数据库存储层面可以为空,而blank为表单验证层面可以填写空值

3.choices

一个二元组的列表或元组,元组中第一个值为真正在数据库中存储的值,第二个值为该选项的描述

class studentModel(models.Model):
	GENDER_CHOICES = [
        (1, '男'),
        (2, '女'),
        (3, '保密'),
    ]
    gender = models.IntegerField(verbose_name='性别', default=3, choices=GENDER_CHOICES)

4.db_column

数据库中用来表示该字段的名称,如果未指定,那么 Django 将会使用Field名作为字段名

5.db_index

当该值为True时,为该字段创建索引

6.default

为字段提供默认值

7.primary_key

设置该值为True时,该字段成为模型的主键字段,一个模型类同时只能有一个主键

如果一个表中不存在任意一个设置好的主键字段,django 会自动设置一个自增AutoField字段来充当主键,该值可以用pkid方式获取。主键的设置还意味着,null=Falseunique=True

8.unique

如果该值为True,代表这个数据在当前的表中有唯一值,这个字段还会在模型层验证存储的数据是否唯一

9.verbose_name

给字段的一个可读性更高的名称,如果没有设置该值,字段名中的下换线转换成空格,作为当前字段的数据库中名称


三、模型类元选项

    在模型类的Meta类中,可以提供一系列的元选项,可以方便对该模型类进行属性设置或约束等。

class TestTable(models.Model):class Meta:
        db_table= 'test'
        verbose_name_plural = '测试表'

1.abstract

代表当前模型类为抽象基类,不会创建真正的数据表,只是为了其他模型类继承使用

abstract = True

2.app_label

当模型类被定义在了其他 app 下,这个属性用来描述当前表属于哪个 app 应用

app_label = "MyApp"

3.abstract

代表当前模型类为抽象基类,不会创建真正的数据表,只是为了其他模型类继承使用

abstract = True

4.db_table

    当前模型类所对应的表名,未设置时,django 默认将表名与 app 名由下划线组成,作为表名
    这个表名为真实在数据库中所使用的,所以该元选项的使用应在数据表创建之前
    如果在表已经存在的情况下去修改,会导致数据库内表与模型类表名不一致而查找不到报错

5.ordering

1.当前表中的数据存储时的排序规则,这是一个字段名的字符串,可以是一个列表或元组;
2.每一个字符串前可以使用"-“来倒序排序,使用”?"随机排序
3.ordering 排序规则的添加,也会增加数据库的开销

ordering = ['-birthday', 'age']
#先按照 birthday 倒序排序,再按照 age 字段进行排序。

6.verbose_name

一般设置该表展示时所用的名称,名称被自动处理为复数,字符串后加一个"s"

ordering = ['-birthday', 'age']
#先按照 birthday 倒序排序,再按照 age 字段进行排序。

7.verbose_name_plural

verbose_name功能相同,但是不会自动在字符串后加"s"以表复数
设置表的复数名称

8.ordering

1.当前表中的数据存储时的排序规则,这是一个字段名的字符串,可以是一个列表或元组;
2.每一个字符串前可以使用"-“来倒序排序,使用”?"随机排序
3.ordering 排序规则的添加,也会增加数据库的开销

ordering = ['-birthday', 'age']
#先按照 birthday 倒序排序,再按照 age 字段进行排序。

四、ORM增删改查

0.ORM的增删改查

#   增  
    1、obj = 模型类(属性=数据)  obj.save()
    2、模型类.objects.create(属性=数据)
#   查 
    模型类.objects.all()  模型类.objects.get() 模型类.objects.filter()
#   删  
   obj = 模型类.objects.get()
    obj.delete()
    模型类.objects.filter(属性=条件).delete()
#   改  
    obj = 模型类.objects.get()
    obj.属性=新值
    obj.save()
    模型类.objects.filter(属性=条件).update(属性=新值)

注意:
	1.增:save()没有返回值,create()一步到位
	2.查:all()filter()、exclude()、get()3.查找时的一些特殊字段的使用:
	order_by()
		Person.objects.order_by('age')
		Person.objects.all().order_by('-age')
	4.count():返回数据库中对应字段的个数,并且该函数永远不会引发异常
	5.values():返回一个查询集结果,但是迭代访问时返回的是字典,而不是数据实例对象
	models.Person.objects.all().values()
	models.Person.objects.values()
	6.链式过滤条件
	

1.增加数据

新建一个子应用 news

# news/models.py
from django.db import models

# Create your models here.
class newsModel(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    visit_num = models.IntegerField(default=0)
    good_num = models.IntegerField(default=0)
    pub_date = models.DateTimeField(default='2024-5-30')
    def __str__(self):
        return self.title
    class Meta:
        db_table = 'news'
        verbose_name_plural = '新闻表'

创建对象:

# news/views
def addData(request):
    # 添加数据的两种方式
    # n1 = newsModel()
    # n1.title = "方式一:新闻标题"
    # n1.content = "方式一:新闻内容"
    # n1.save()

    n2 = newsModel.objects.create(title="方式二:新闻标题",content="方式二:新闻内容")

    return HttpResponse('{"message":"增加数据成功!"}',content_type="application/json")

2.查找对象

def queryData(request):
    # 1.查询所有,并返回结果集(以id为降序查询)
    # n1 = newsModel.objects.all().order_by('-id')
    # for i in n1:
    #     print(i.title)
    #     print(i.content)
    #     print(i.visit_num)
    #     print(i.good_num)
    #     print(i.pub_date)
    #     print("-"*16)

    # 2.使用get查询的时候,默认使用id,如果使用其他数据查询,保证数据唯一
    # try:
    #     n2 = newsModel.objects.get(id=2)
    # except Exception as e:
    #     print(e)

    # 3.返回的也是根据条件过滤的结果集(阅读量大于100,点赞量大于50)
    n3 = newsModel.objects.filter(visit_num__gt=100).filter(good_num__gt=50)
    for i in n3:
        print(i.title)
        print(i.content)
        print(i.visit_num)
        print(i.good_num)
        print(i.pub_date)
        print("-"*16)
    #4.查找符合条件以外的数据
    # n4 = newsModel.objects.exclude(good_num=0)

    return HttpResponse('{"message":"返回数据展示!"}',content_type="application/json")

查询中用到的一些字段:

a.order_by(*field)

默认情况下,数据表使用模型类中的 Meta 中指定的 ordering 选项进行排序
也可以通过使用 order_by 函数进行查询结果的排序

Person.objects.order_by('age')
Person.objects.all().order_by('-age')
b.count()

返回数据库中对应字段的个数,并且该函数永远不会引发异常

models.Person.objects.filter(age=20).count()
Person.objects.count()
c.order_by(*field)

默认情况下,数据表使用模型类中的 Meta 中指定的 ordering 选项进行排序
也可以通过使用 order_by 函数进行查询结果的排序

Person.objects.order_by('age')
Person.objects.all().order_by('-age')

注意:所以有时使用已生产好的结果集,通过len*函数获取长度,这种方式效率会更高;count方法的调用会导致额外的数据库查询

d.values(*fields)

返回一个查询集结果,但是迭代访问时返回的是字典,而不是数据实例对象

models.Person.objects.all().values()
models.Person.objects.values()

3.链式过滤条件

contains:

大小写敏感的匹配查询,也是 like,注意转换后查询条件的两侧都有%

Person.objects.filter(name__contains='好')

icontains:

大小写不敏感的匹配查询

Person.objects.filter(name__icontains='好')

range:

在某个范围内进行查询

Person.objects.filter(id__range=(1,6))

in:

在某个范围内进行查询

Person.objects.filter(id__in=(1,6))
Person.objects.filter(id__in=[1,6])

exact:

如果在查询过程中,没有提供查询类型(没有双下划线),那么查询类型就会被默认指定为exact,这是一种严格查找的方式,用来在数据库中查找和查询时的关键词参数完全一致的内容

Person.objects.filter(account='root')
Person.objects.filter(account__exact='root')

iexact:

忽略大小写的匹配

Person.objects.filter(account__iexact='root')
#匹配到的结果可能是 Root,ROot,ROOt,ROOT

startswith、endswith:

分别匹配开头和结尾,区分大小写

Person.objects.filter(passwd__startswith='admin')
# 匹配以 admin 开头的数据

istartswith、iendswith:

分别匹配开头和结尾,忽略大小写

Person.objects.filter(passwd__istartswith='admin')
匹配以不区分大小写的字符串 admin 为开头的数据

gte:

大于或等于

Person.objects.filter(reg_data__gte=datetime.date.today)

lte:

小于或等于

Person.objects.filter(reg_data__lte=datetime.date.today)

4.修改对象

def updateData(request):
    # 1.查询单个数据,进行修改(id = 1)
    n1 = newsModel.objects.get(id=1)
    n1.title = "修改后的新闻标题"
    n1.content = "修改后的新闻内容"
    n1.save()

    #2.通过过滤结果集,修改数据
    # n2 = newsModel.objects.filter(visit_num=0).update(visit_num=150)
    # n3 = newsModel.objects.filter(good_num=0).update(good_num=75)
    # print(n2)
    # print(n3)

    return HttpResponse('{"message":"修改数据成功!"}',content_type="application/json")

5.删除对象

def removeData(request):
    # 1.全部删除
    # newsModel.objects.all().delete()

    # 2.先get查询,再删除数据(id = 2)
    n1 = newsModel.objects.get(id=2)
    n1.delete()

    # 3.根据filter过滤,删除查询到的数据(点赞量等于0的数据)
    # n2 = newsModel.objects.filter(good_num=0).delete()
    # print(n2)
    return HttpResponse('{"message":"删除数据成功!"}',content_type="application/json")

6.ORM的Q、F查询

Q查询:

之前的查询都是对象的属性与常量值比较,两个属性怎么比较呢?

  • 使用F对象,被定义在django.db.models中。
  • 可以在F对象上使用算数运算。
from django.db.models import F

F('属性名')  # 注意:属性名是字符串形式

1.查询阅读量大于评论量的图书
Book.objects.filter(bread__gt=F('bcomment'))

2.查询阅读量是评论量2倍的图书
Book.objects.filter(bread=F('bcomment')*2)

3.查询阅读量比评论量多100的图书
Book.objects.filter(bread=F('bcomment')+100)

F查询:

  • 多个过滤器逐个调用表示逻辑与and关系,同sql语句中where部分的and关键字。
  • 如果需要实现逻辑或or的查询,需要使用Q对象结合逻辑运算符Q对象被义在django.db.models中。
  • Q对象可以使用&|连接,&表示逻辑与,|表示逻辑或。
from django.db.models import Q

Q(属性名__运算符=)  # 注意: 属性名不是字符串,不能加引号

1.查询id阅读量大于20id小于3的图书
Book.objects.filter(bcomment__gt=20).filter(id__lt=3)  # 多个过滤器连续操作
Book.objects.filter( Q(bcomment__gt=20) & Q(id__lt=3) )  # 使用Q对象和逻辑运算符

2.查询阅读量大于20,或编号小于3的图书
Book.objects.filter( Q(bcomment__gt=20) | Q(id__lt=3) )  # 只能使用Q对象

7.QuerySet

查询结果集:表示从数据库中获取的对象集合。

当调用如下过滤器方法时,Django会返回查询集(而不是简单的列表):

  • all():返回所有数据。
  • filter():返回满足条件的数据。
  • exclude():返回满足条件之外的数据。
  • order_by():对结果进行排序。
# 1.惰性查询-懒加载
# 2.缓存
queryset[0].name
queryset[0:2]

注意:创建结果集的过程不涉及任何数据库的操作,查询工作是惰性的,在上面的查询方式中,查询代码不会实际访问数据库,只有查询集在真正使用时,django 才会访问数据库


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/665038.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL 命令总结篇-思维导图

一些常用命令以思维导图形式总结在这里了,掌握这些进行MySQL基本操作绝对没问题,加油!友友们可以根据这些思维导图进行知识总结。 目录 一、快速上手 二、SQL 语句分类(DDL、DML、DQL、DCL) 三、数据类型 四、约束…

数字水印 | 图像噪声攻击(高斯/椒盐/泊松/斑点)

目录 Noise Attack1 高斯噪声(Gaussian Noise)2 椒盐噪声(Salt and Pepper Noise)3 泊松噪声(Poisson Noise)4 斑点噪声(Speckle Noise)5 完整代码 参考博客:Python…

零基础学会asp.net做网站/公众号/小程序之三:实战初体验(简单程序教学)

关注我,持续分享逻辑思维&管理思维&面试题; 可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导; 博主在互联网大厂深耕近二十年,从一线码农做起,到人工智能公司副总裁。希望把过往经验总结出来&#xff0…

对称二叉树(oj题)

一、题目链接https://leetcode-cn.com/problems/symmetric-tree/ 二、题目思路 给你一个二叉树的根节点 root , 检查它是否轴对称的思路: 1.将该树的左子树和右子树,当做两棵树,调用 判断两棵树是否对称相等的函数 2.判断两颗树是否对称相…

【网络安全】Web安全学习-前言及先导

一、网络安全概述 网络安全是指网络系统的硬件、软件及其系统中的数据受到保护,不因偶然的或者恶意的原因遭到破坏、更改、泄露,系统能连续可靠的正常运行,网络服务不中断。简单来说。就是要保障我们的网络环境安全稳定,不被人破…

深入理解linux文件系统与日志分析

深入理解linux文件系统与日志分析 linux文件系统: 文件是存储在硬盘上的,硬盘上的最小存储单位是扇区,每个扇区的大小是512字节。 inode:元信息(文件的属性 权限,创建者,创建日期等等) block…

【Python】解决Python报错:AttributeError: ‘generator‘ object has no attribute ‘xxx‘

🧑 博主简介:阿里巴巴嵌入式技术专家,深耕嵌入式人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍:分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向…

【核心动画-关键帧动画-CAKeyframeAnimation Objective-C语言】

一、接下来,我们来说这个关键帧动画, 1.我们把之前的基本动画,这一坨代码,备份到test1方法里边, 然后,开始说我们的关键帧动画,步骤都是一样的,都是三大步: // 关键帧动画 // 1.做什么动画 // 2.怎么做动画 // 3.对谁做动画 1)做什么动画 第一,我们现在要创建…

计算机图形学入门04:视图变换

1.MVP变换 将虚拟场景中的模型投影到屏幕上,也就是二维平面上,需要分三个变换。 1.首先需要知道模型的位置,也就是前面提到的基本变换,像缩放、平移,旋转,也称为模型(Model)变换。 2.然后需要知道从…

STM32定时器与PWM对LED灯的控制

文章目录 一、定时器——Timer(一)概念(二)分类(三)功能(四)结构1.模块一——时基单元2.模块二——输出比较模块 二、实验内容(一)标准库点亮LED灯1.实验说明…

99.网络游戏逆向分析与漏洞攻防-ui界面的设计-角色信息显示的界面与功能

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 如果看不懂、不知道现在做的什么,那就跟着做完看效果,代码看不懂是正常的,只要会抄就行,抄着抄着就能懂了 内容…

新型 Meterpreter 后门能够在图片中隐藏恶意代码

据Cyber Security News消息,ANY.RUN 沙盒分析了一种被称为Meterpreter 的新型后门恶意软件,能利用复杂的隐写技术将恶意有效载荷隐藏在看似无害的图片文件中。 基于Meterpreter的攻击从一个包含 PowerShell 脚本的 .NET 可执行文件开始,该脚…

解决VSCode右键没有Open In Default Browser问题

在VSCode进行Web小程序测试时,我们在新建的HTML文件中输入 !会自动生成页面代码骨架,写入内容后,我们想要右键在浏览器中预览。发现右键没有“Open In Default Browser”选项。原因是没有安装插件。 下面是解决方案:首先在VSCode找…

【CSS布局】响应式设计原则以及双飞翼布局圣杯布局

历史小剧场 温体仁未必是奸臣,钱谦益未必是好人,不需要惊讶,历史往往跟你所想的并不一样。英雄可以写成懦夫,能臣可以写成奸臣,史实并不重要,重要的是,谁来写。----《明朝那些事儿》 响应式设计…

【计算机毕设】基于SpringBoot的学生心理咨询评估系统设计与实现 - 源码免费(私信领取)

免费领取源码 | 项目完整可运行 | v:chengn7890 诚招源码校园代理! 1. 研究目的 随着社会的快速发展和竞争压力的增加,学生心理健康问题日益突出。设计和实现一个基于SpringBoot的学生心理咨询评估系统,旨在…

【Seafile】Seafile容器版文件删除后存储空间不释放问题解决

Seafile是一款非常优秀的网盘系统,我们可以根据官方文档,在本地虚拟机研究Seafile免费版的安装和使用,安装建议采用使用docker容器的方式。 不过在使用过程中,刚接触的小伙伴可能会遇到这样的问题: 删除网盘里面的文…

煤矿输送设备无人化运维巡检解决方案

一、煤矿行业目前存在的挑战和难题 煤矿行业面临着复杂的环境,如粉尘、潮湿、高温、高瓦斯等,对巡检设备和人员安全有威胁。并且设备分布广、需要长时间作业,全面巡检难度大、对巡检工作的耐力和持续性要求高。而煤矿输送设备无人化运维巡检…

OAK相机如何将 YOLOv10 模型转换成 blob 格式?

编辑:OAK中国 首发:oakchina.cn 喜欢的话,请多多👍⭐️✍ 内容可能会不定期更新,官网内容都是最新的,请查看首发地址链接。 Hello,大家好,这里是OAK中国,我是Ashely。 专…

MedSAM 学习笔记(续):训练自定义数据集

1、下载官方权重 官方的预训练权重:https://dl.fbaipublicfiles.com/segment_anything/sam_vit_b_01ec64.pth 下载后保存在:work_dir/SAM/sam_vit_b_01ec64.pth 目录 2、摆放数据集 因为MedSAM 分割模型需要对3D数据集进行切片处理,也就是对nii.gz 数据处理成 npy 格式 …

计算机图形学入门05:投影变换

1.投影变换 上一章已经介绍了投影变换,就是将三维图像投影到二维平面上,而投影变换又分为正交投影(Orthographic Projection)和透视投影(Perspective Projection)。如下图: 正交投影 没有近大远小的现象,无论图形与视点距离是远是…