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

news2025/7/15 4:58:39

在这里插入图片描述

系列文章目录

  • 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 才会访问数据库


在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Arxiv AI 综述列表(2024.05.27~2024.05.31) VLM

公众号:EDPJ(进 Q 交流群:922230617 或加 VX:CV_EDPJ 进 V 交流群) 每周末更新,完整版进群获取。 Q 群在群文件,VX 群每周末更新。 目录 1. An Introduction to Vision-Language Modeling …

Semaphore信号量限制访问

文章目录 什么是Semaphore使用Semaphoreacquire函数release函数 什么是Semaphore Semaphore是一个计数信号量,用于控制同时访问特定资源的线程数量,以维护资源的访问控制和确保系统的线程安全。Semaphore可以被视为一个包含若干许可(permit&a…

网络分层与各层网络协议介绍

一.OSI七层模型 1.OSI(Open Systems Interconnection)七层模型是由国际标准化组织(ISO)提出的一种网络通信协议的参考模型,用于标准化网络通信的过程。 OSI模型将网络通信分为七个层次,每个层次负责不同的…

ChatGPT产品创意,直接出概念图

直接问,“给我一个创意点子” AI7号 它推荐我做一个智能家居植物管理系统,嗯,很小众的样子。直接让它出一张概念图吧。 像模像样,一张图太单薄了,再来5张。 呃...做了4张,下面还有每张图的说明。 你觉得怎…

SpringBoot-世界杯足球赛网站-28567

Springboot世界杯足球赛网站 摘 要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题。针对世界杯足球赛…

zabbix事件告警监控:如何实现对相同部件触发器告警及恢复的强关联

有一定Zabbix使用经验的小伙伴可能会发现,接收告警事件时,其中可能包含着大量不同的部件名,同一部件的事件在逻辑上具有很强关联性,理论上应保持一致的告警/恢复状态,但Zabbix默认并未对它们进行关联,直接后…

HarmonyOS鸿蒙学习笔记(27)resources目录说明

resources目录说明 目录结构目录说明base目录rawfile目录resfile目录资源组目录 参考资料 目录结构 在HarmonyOS的项目结构中,有resources目录,用于存放应用/服务所用到的资源文件,如图形、多媒体、字符串、布局文件等。关于资源文件&#x…

DAQmx Connect Terminals (VI) 信号路由作用及意义

DAQmx Connect Terminals是一个LabVIEW虚拟仪器(VI),用于配置和连接数据采集系统中的物理终端或虚拟终端。这一功能在配置复杂的数据采集(DAQ)系统时非常重要,因为它允许用户在不改变硬件连接的情况下&…

使用Spring Boot自定义注解 + AOP实现基于IP的接口限流和黑白名单

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~ 🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Mi…

德人合科技——天锐绿盾内网安全管理软件 | -文档透明加密模块

天锐绿盾文档加密功能能够为各种模式的电子文档提供高强度加密保护,丰富的权限控制以及灵活的应用管理,帮助企业构建更严密的立体保密体系。 PC地址: https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee ————…

VSCODE 常用快捷键

快捷按键 注释 CTRL /CTRL KSHIFT ALT A取消注释 CTRL /CTRL KSHIFT ALT A搜索文件 Ctrl P移动到某一行 Ctrl g打开一个新窗口 Ctrl Shift N关闭窗口 Ctrl Shift W新建文件 Ctrl N文件间切换 Ctrl Tab全部文件搜索 Ctrl Shift F全屏 F11 打开文件出现中文乱码 文件右下角…

极验4点选逆向 JS逆向分析 最新版验证码

目录 声明! 一、请求流程分析 二、加密参数w与payload 三、参数w生成位置 四、结果展示: 原创文章,请勿转载! 本文内容仅限于安全研究,不公开具体源码。维护网络安全,人人有责。 声明! 本文章…

268 基于matlab的模拟双滑块连杆机构运动

基于matlab的模拟双滑块连杆机构运动,并绘制运动动画,连杆轨迹可视化输出,并输出杆件质心轨迹、角速度、速度变化曲线。可定义杆长、滑块速度,滑块初始位置等参数。程序已调通,可直接运行。 268 双滑块连杆机构运动 连…

Dinky DorisCDC 整库同步到 Doris

doris flinkcdc语法参考 Flink Doris Connector - Apache Doris 参考: Doris Flink DolphinScheduler Dinky 构建开源数据平台_dinky dolphinscheduler flink-CSDN博客

【SpringMVC】_SpringMVC实现用户登录

目录 1、需求分析 2、接口定义 2.1 校验接口 请求参数 响应数据 2.2 查询登录用户接口 请求参数 响应数据 4、服务器代码 5、前端代码 5.1 登录页面login.html 5.2 首页页面index.html 6、运行测试 1、需求分析 用户输入账号与密码,后端校验密码是否正确&a…

使用opencv 进行车牌位置检测的源代码

效果: 这一个车牌识别系统中的预处理函数,其主要目的是对输入的车牌图片进行一系列的图像处理操作,以便后续的车牌识别算法能够更准确地识别出车牌。 整个函数的流程是:读取图像 -> 缩放 -> 灰度化 -> 去噪 -> 边缘检测 -> 形态学操作 -> 轮廓检测 ->…

科普健康短视频:成都鼎茂宏升文化传媒公司

科普健康短视频:引领健康知识新潮流 在数字化时代的浪潮中,短视频以其短小精悍、直观易懂的特点,迅速成为大众获取信息的重要渠道。其中,科普健康短视频更是凭借其科学、权威、实用的内容,吸引了大量关注健康的观众。…

【C++ ——— 继承】

文章目录 继承的概念即定义继承概念继承定义定义格式继承关系和访问限定符继承基类成员访问方式的变化 基类对象和派生类对象的赋值转换继承中的作用域派生类中的默认成员函数继承与友元继承与静态成员菱形继承虚继承解决数据冗余和二义性的原理继承的总结继承常见笔试面试题 继…

Unity中模拟生成正态分布的一种方式

using System; using System.Collections; using System.Collections.Generic; using Unity.Mathematics; using UnityEngine;public class MathFunction : MonoBehaviour {private void Start(){//key 范围 0-99 表示 0% 到 99%Dictionary<int,uint> m new Dictionary&…

Jmeter性能测试-【关联,提取器】

新知识点 关联&#xff1a; 正则表达式提取器 边界提取器 XPath提取器 JSON提取器 梳理框架 1. Jmeter基础 定义&#xff1a;Jmeter是一个开源的性能测试工具&#xff0c;主要用于Web应用和各种服务的性能测试。 主要功能&#xff1a;可以模拟多用户并发访问&#xff0c;测…