当前位置: 首页 > news >正文

django操作orm整套

1、创建项目

django-admin startproject bookmanager

2、创建应用

python manage.py startapp book

3、数据库配置

在settings.py中保存了数据库的连接配置信息,Django默认初始配置使用sqlite数据库。
DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3','NAME': os.path.join(BASE_DIR, 'db.sqlite3'),}
}

使用MySQL数据库首先需要安装驱动程序

pip install PyMySQL

在Django的工程同名子目录的__init__.py文件中添加如下语句

import pymysqlpymysql.install_as_MySQLdb()

修改DATABASES配置信息

DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','HOST': '127.0.0.1',  # 数据库主机'PORT': 3306,  # 数据库端口'USER': 'root',  # 数据库用户名'PASSWORD': 'mysql',  # 数据库用户密码'NAME': 'book'  # 数据库名字}
}

4、数据库表创建

1)字段类型

类型说明
AutoField自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性
BooleanField布尔字段,值为True或False
NullBooleanFieldNullBooleanField
CharField字符串,参数max_length表示最大字符个数
TextField大文本字段,一般超过4000个字符时使用
IntegerField整数
DecimalField十进制浮点数, 参数max_digits表示总位数, 参数decimal_places表示小数位数
FloatField浮点数
DateField日期, 参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为False; 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为False; 参数auto_now_add和auto_now是相互排斥的,组合将会发生错误
TimeField时间,参数同DateField
DateTimeField日期时间,参数同DateField
FileField上传文件字段
ImageField继承于FileField,对上传的内容进行校验,确保是有效的图片

2) 选项

选项说明
null如果为True,表示允许为空,默认值是False
blank如果为True,则该字段允许为空白,默认值是False
db_column字段的名称,如果未指定,则使用属性的名称
db_index若值为True, 则在表中会为此字段创建索引,默认值是False
default默认值
primary_key若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用
unique如果为True, 这个字段在表中必须有唯一值,默认值是False

3) 外键
在设置外键时,需要通过on_delete选项指明主表删除数据时,对于外键引用表数据如何处理,在django.db.models中包含了可选常量:

类型说明
CASCADE级联,删除主表数据时连通一起删除外键表中数据
PROTECT保护,通过抛出ProtectedError异常,来阻止删除主表中被外键应用的数据
SET_NULL设置为NULL,仅在该字段null=True允许为null时可用
SET_DEFAULT设置为默认值,仅在该字段设置了默认值时可用
SET()设置为特定值或者调用特定方法
DO_NOTHING不做任何操作,如果数据库前置指明级联性,此选项会抛出IntegrityError异常

配置文件夹

INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth',# ...其他默认应用'book',  # 添加你的应用名称
]

book的models.py

from django.db import models# Create your models here.
# 准备书籍列表信息的模型类
class BookInfo(models.Model):# 创建字段,字段类型...name = models.CharField(max_length=20, verbose_name='名称')pub_date = models.DateField(verbose_name='发布日期',null=True)readcount = models.IntegerField(default=0, verbose_name='阅读量')commentcount = models.IntegerField(default=0, verbose_name='评论量')is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')class Meta:db_table = 'bookinfo'  # 指明数据库表名verbose_name = '图书'  # 在admin站点中显示的名称def __str__(self):"""定义每个数据对象的显示信息"""return self.name# 准备人物列表信息的模型类
class PeopleInfo(models.Model):GENDER_CHOICES = ((0, 'male'),(1, 'female'))name = models.CharField(max_length=20, verbose_name='名称')gender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name='性别')description = models.CharField(max_length=200, null=True, verbose_name='描述信息')book = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name='图书')  # 外键is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')class Meta:db_table = 'peopleinfo'verbose_name = '人物信息'def __str__(self):return self.name

生成迁移文件

python manage.py makemigrations

同步到数据库中

python manage.py migrate

添加数据

insert into bookinfo(name, pub_date, readcount,commentcount, is_delete) values
('射雕英雄传', '1980-5-1', 12, 34, 0),
('天龙八部', '1986-7-24', 36, 40, 0),
('笑傲江湖', '1995-12-24', 20, 80, 0),
('雪山飞狐', '1987-11-11', 58, 24, 0);insert into peopleinfo(name, gender, book_id, description, is_delete)  values('郭靖', 1, 1, '降龙十八掌', 0),('黄蓉', 0, 1, '打狗棍法', 0),('黄药师', 1, 1, '弹指神通', 0),('欧阳锋', 1, 1, '蛤蟆功', 0),('梅超风', 0, 1, '九阴白骨爪', 0),('乔峰', 1, 2, '降龙十八掌', 0),('段誉', 1, 2, '六脉神剑', 0),('虚竹', 1, 2, '天山六阳掌', 0),('王语嫣', 0, 2, '神仙姐姐', 0),('令狐冲', 1, 3, '独孤九剑', 0),('任盈盈', 0, 3, '弹琴', 0),('岳不群', 1, 3, '华山剑法', 0),('东方不败', 0, 3, '葵花宝典', 0),('胡斐', 1, 4, '胡家刀法', 0),('苗若兰', 0, 4, '黄衣', 0),('程灵素', 0, 4, '医术', 0),('袁紫衣', 0, 4, '六合拳', 0);

5、直接窗口操作

python manage.py shell

在这里插入图片描述

5、新增

from book.models import BookInfo,PeopleInfo
是一种新增
books = BookInfo(name='大得',pub_date='2010-1-1'
)
books.save()第二种新增
PeopleInfo.objects.create(name='大得',book=books
)

6、修改

from book.models import PeopleInfo, BookInfo
是一种修改
person = PeopleInfo.objects.get(name='itheima')
person.name = '大得2'
person.save()
是二种修改
PeopleInfo.objects.filter(name='itcast').update(name='大得')

7、删除

from book.models import PeopleInfo, BookInfo
是一种删除
person = PeopleInfo.objects.get(name='大得')
person.delete()
是二种删除
BookInfo.objects.filter(name='python入门').delete()

8、基础查询

1、基础查询

基础查询
1、返回一个对象
data = BookInfo.objects.get(id=1)
data.name2、查全部
BookInfo.objects.all()过滤查询
filter过滤出多个结果
exclude排除掉符合条件剩下的结果
get过滤单一结果查询id等于1的数组
data = BookInfo.objects.filter(id=1)
data[0].name模糊查询__contains
BookInfo.objects.filter(name__contains='大')空查询
isnull:是否为null
BookInfo.objects.filter(name__isnull=True)范围查询
in:是否包含在范围内
BookInfo.objects.filter(id__in=[1,3,5])比较查询
gt大于 (greater then)
gte大于等于 (greater then equal)
lt小于 (less then)
lte小于等于 (less then equal)
BookInfo.objects.filter(id__gt=3)不等于的运算符,使用exclude()过滤器。
result = Book.objects.exclude(author="张三")

2、F和Q对象,F判断sql两个字段,Q条件

# readcount数据库字段1,commentcount数据库字段2
from django.db.models import F
BookInfo.objects.filter(readcount__gt=F('commentcount'))
乘2
BookInfo.objects.filter(readcount__gt=F('commentcount')*2)Q对象,&是and,|是or
where = Q(id__gt=1)
where  &= Q(name_id__gt=1)
where  &= Q( Q(name_id__gt=1) |  Q(name_id__gt=1))
BookInfo.objects.filter(Q(readcount__gt=20))

3、聚合函数

使用aggregate()过滤器调用聚合函数。聚合函数包括:Avg平均,Count数量,Max最大,Min最小,SumBookInfo.objects.aggregate(Sum('readcount'))获得总数也可以这样写
BookInfo.objects.count()

4、 排序

# 默认升序
BookInfo.objects.all().order_by('id')
# 降序
BookInfo.objects.all().order_by('-id')

9、关联查询

由一到多的访问语法:
一对应的模型类对象.多对应的模型类名小写_set 例:#peopleinfo是另外一张表,有一个book_id,_set方法是模型默认方法,会自动去找book_id,在主模型中无需有这个字段,peopleinfo模型有book外键
book = BookInfo.objects.get(id=1)
book.peopleinfo_set.all()由多到一的查询语法:
#直接点book就可以了,因为有外键关联
person = PeopleInfo.objects.get(id=1)
person.book访问一对应的模型类关联对象的id语法:
person = PeopleInfo.objects.get(id=1)
person.book_id

10、多模型查询

由多模型类条件查询
关联模型类名小写__属性名__条件运算符=值BookInfo通过peopleinfo有book外键
book = BookInfo.objects.filter(peopleinfo__name='郭靖')
book = BookInfo.objects.filter(peopleinfo__description__contains='八')PeopleInfo有book外键模型
PeopleInfo.objects.filter(book__name='天龙八部')

11、分页

from book.models import PeopleInfo, BookInfo
#导入分页类
from django.core.paginator import Paginator
#查询数据
books = BookInfo.objects.all()
#创建分页实例
paginator=Paginator(books,2)
#获取指定页码的数据
page_skus = paginator.page(1)
#获取总页数
total_page=paginator.num_pages# 获取当前页的数据列表(核心)
current_page_data = page_skus.object_list
print(current_page_data)
paginator.count:总数据条数
paginator.num_pages:总页数(整数)
page_skus.number:当前页码
page_skus.has_next():是否有下一页
page_skus.has_previous():是否有上一页
page_skus.next_page_number():下一页页码(如果存在)
page_skus.previous_page_number():上一页页码(如果存在

12、多对多

假设我们有两个模型:Book(书籍)和Author(作者),一个书籍可以有多个作者,一个作者可以写多本书。

from django.db import modelsclass Author(models.Model):name = models.CharField(max_length=50, verbose_name="作者姓名")age = models.IntegerField(verbose_name="年龄")def __str__(self):return self.nameclass Book(models.Model):title = models.CharField(max_length=100, verbose_name="书名")publish_date = models.DateField(verbose_name="出版日期")# 定义多对多关系:一本书关联多个作者authors = models.ManyToManyField(Author, related_name="books", verbose_name="作者")def __str__(self):return self.title
关键参数说明:
ManyToManyField(Author):表示与Author模型建立多对多关系
related_name="books":定义反向关联名称,通过作者可以用author.books查询其所有书籍
Django 会自动创建中间表(无需手动定义),用于存储多对多关系定义模型后,执行迁移命令生成数据表:
python manage.py makemigrations
python manage.py migrate

多对多关系的操作

# 创建作者
author1 = Author.objects.create(name="张三", age=30)
author2 = Author.objects.create(name="李四", age=35)# 创建书籍
book1 = Book.objects.create(title="Django入门", publish_date="2023-01-01")
book2 = Book.objects.create(title="Python高级编程", publish_date="2022-05-10")# 给书籍添加作者(多对多关联)
book1.authors.add(author1, author2)  # 一本书关联多个作者
book2.authors.add(author1)  # 另一本书关联一个作者# 也可以通过作者反向关联书籍
author2.books.add(book2)  # 作者李四也关联book2

查询关联数据

# 1. 通过书籍查作者(正向查询)
book = Book.objects.get(title="Django入门")
authors = book.authors.all()  # 获取这本书的所有作者
print(f"{book.title}的作者:{[a.name for a in authors]}")# 2. 通过作者查书籍(反向查询,使用related_name)
author = Author.objects.get(name="张三")
books = author.books.all()  # 获取这个作者的所有书籍
print(f"{author.name}的书籍:{[b.title for b in books]}")# 3. 过滤查询(查询包含特定作者的书籍)
books = Book.objects.filter(authors__name="张三")  # 查询张三写的所有书

修改关联关系

book = Book.objects.get(title="Django入门")# 替换关联(移除现有所有作者,添加新作者)
book.authors.set([author1])  # 只保留author1# 添加新关联(不会移除现有关联)
book.authors.add(author2)  # 重新添加author2# 移除某个关联
book.authors.remove(author1)  # 移除author1

清空关联

book = Book.objects.get(title="Django入门")
book.authors.clear()  # 清空这本书的所有作者关联(不会删除作者本身)

删除数据

# 删除作者(会自动删除中间表中的关联记录)
author = Author.objects.get(name="张三")
author.delete()  # 同时删除该作者与所有书籍的关联# 删除书籍(同理,会自动删除中间表关联)
book = Book.objects.get(title="Django入门")
book.delete()

自定义中间表(可选)
如果需要在多对多关系中存储额外信息(如 “作者在书中的角色”),可以自定义中间表:

class BookAuthor(models.Model):book = models.ForeignKey(Book, on_delete=models.CASCADE)author = models.ForeignKey(Author, on_delete=models.CASCADE)role = models.CharField(max_length=50, verbose_name="角色(如:主编、合著)")  # 额外字段join_date = models.DateField(verbose_name="参与日期")  # 额外字段class Book(models.Model):# ...其他字段# 通过through指定自定义中间表authors = models.ManyToManyField(Author, through=BookAuthor, through_fields=('book', 'author'))

使用自定义中间表时,关联操作需要通过中间表模型进行:

# 添加关联(带额外信息)
BookAuthor.objects.create(book=book1,author=author1,role="主编",join_date="2022-10-01"
)

多对多关系是 Django ORM 中非常灵活的关联方式,适用于需要双向多关联的场景。核心是通过ManyToManyField定义关系,然后使用add()/remove()/set()等方法管理关联。

http://www.lryc.cn/news/606650.html

相关文章:

  • 学习设计模式《二十》——解释器模式
  • 如何使用Postman做接口测试
  • curl命令使用
  • 【机器学习与数据挖掘实战 | 医疗】案例20:基于交叉验证和LightGBM算法的糖尿病遗传风险预测
  • 机器学习②【字典特征提取、文本特征处理(TF-IDF)、数据标准化与归一化、特征降维】
  • 解决IDEA无法克隆GitHub上的工程的问题
  • 解决IDEA中MAVEN项目总是将LANGUAGE LEVEL重置的问题
  • SSL 剥离漏洞
  • 把上次做的图片的API改成国内版,让图片返回速度提升一个档次
  • 对于前端闭包的详细理解
  • LeetCode热题100——146. LRU 缓存
  • Typora v1.10.8 好用的 Markdown 编辑器
  • Linux 系统监控脚本实战:磁盘空间预警、Web 服务与访问测试全流程
  • ACM SIGCOMM 2024论文精选-01:5G【Prism5G】
  • 数据处理--生成Excel文档
  • 18.若依框架中的xss过滤器
  • 南太平洋金融基建革命:斐济-巴新交易所联盟的技术破局之路 ——从关税动荡到离岸红利,跨境科技如何重塑太平洋资本生态
  • 基于html,css,jquery,django,lstm,cnn,tensorflow,bert,推荐算法,mysql数据库
  • 元策联盈:深耕金融领域,赋能行业发展​
  • Apache RocketMQ for AI 战略升级,开启 AI MQ 新时代
  • 视频生成中如何选择GPU或NPU?
  • 《C++初阶之STL》【stack/queue/priority_queue容器适配器:详解 + 实现】(附加:deque容器介绍)
  • Eclipse中导入新项目,右键项目没有Run on Server,Tomcat的add and remove找不到项目
  • Apache RocketMQ 中 Producer(生产者)的详细说明
  • vivado扫描:synth_1 ​ 和 ​Out-of-Context (OOC) Modules Runs​ 的区别(腾讯元宝)
  • Apache RocketMQ 中 Consumer(消费者)的详细说明
  • 超越 ChatGPT:智能体崛起,开启全自主 AI 时代
  • 在VScode里运行并调试C++程序
  • 3-verilog的使用-1
  • 建造者模式及优化