一、使用Django-admin创建Django项目
1、cmd中执行以下命令
django-admin startproject mysqlQuery
2、用pycharm打开如下所示:
3、右下角添加解释器
4、安装Django
pip install django
安装后如下所示:
二、创建app
1、创建名为user的模块
python manage.py startapp user
创建后如下所示:
2、app注册到settings.py中
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'user' ]
3、为app创建一个容器apps,并设置为Sources Root
单击项目名称,右键→new → python package → 命名为apps
并将user模块拖入apps目录里面
效果如下:
4、要实现除了在根目录下找app,还在apps下面找,在settings.py中添加如下代码
import os import sys from pathlib import Path # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent sys.path.insert(0, BASE_DIR) sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
到此为止,后台基本项目创建完毕,启动项目,
python manage.py runserver
控制台打印如下:
(.venv) PS D:\project\pythonProject\mysqlQuery> python manage.py runserver Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them. December 27, 2024 - 10:09:36 Django version 4.2.17, using settings 'mysqlQuery.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK. [27/Dec/2024 10:09:44] "GET / HTTP/1.1" 200 10664 Not Found: /favicon.ico [27/Dec/2024 10:09:44] "GET /favicon.ico HTTP/1.1" 404 2114
浏览器访问:http://127.0.0.1:8000/,效果如下:
三、连接数据库
1、创建类,让类与数据库的表进行关联。
类创建在user/models.py中
class User(models.Model): uid = models.AutoField(primary_key=True,verbose_name="编号") name = models.CharField(max_length=32,verbose_name="姓名") age = models.IntegerField(verbose_name="年龄") join_time = models.DateField(auto_now_add=True) class Meta: managed = True db_table = "user" verbose_name = "用户信息" verbose_name_plural = verbose_name def __str__(self): return "姓名:%s\t 年龄:%s" % (self.name, self.age)
2、在settings.py中连接数据库的参数
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST': '127.0.0.1', # 数据库主机 'PORT': '3306', # 数据库端口 'USER': 'root', # 数据库用户名 'PASSWORD': '123456', # 数据库用户名 'NAME': 'user_manage', # 数据库名称 'OPTIONS': {'init_command': 'SET default_storage_engine=INNODB;'} } }
3、navicate中创建user_manage数据库
4、安装pymysql
pip install pymysql
5、将pymysql初始化到app中
即在user/__init__.py中添加如下内容
import pymysql pymysql.install_as_MySQLdb()
6、用以下两个命令将类映射到表
python manage.py makemigrations
python manage.py migrate
此时查看数据库
user的表结构如下:
手动添加几条数据
四、测试增删改
在manage.py中添加如下代码
import os import sys def main(): """Run administrative tasks.""" os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysqlQuery.settings') import django django.setup() from user import models print(models.User.objects.all()) try: from django.core.management import execute_from_command_line except ImportError as exc: raise ImportError( "Couldn't import Django. Are you sure it's installed and " "available on your PYTHONPATH environment variable? Did you " "forget to activate a virtual environment?" ) from exc execute_from_command_line(sys.argv) if __name__ == '__main__': main()
结果如下:
<QuerySet [<User: 姓名:张三 年龄:21>, <User: 姓名:李思 年龄:20>, <User: 姓名:王思聪 年龄:22>]>
当需要查询主键值字段值的时候,可以使用pk替代主键字段的真正名字。
from user import models print(models.User.objects.filter(pk=1))
结果如下:
<QuerySet [<User: 姓名:张三 年龄:21>]>
Queryset中如果是列表套对象那么可以直接for循环和索引取值。(索引取值不支持负数)
虽然Queryset支持索引但是当Queryset没有数据的时候索引取值会报错,推荐使用first
添加数据create(返回值就是当前创建的数据对象)
user1 = models.User.objects.create(name='赵龙', age=23) print(user1)
结果如下:
姓名:赵龙 年龄:23
利用类实例化对象然后调用save方法创建数据
user2 = models.User() user2.name="田大坑" user2.age = 24 user2.save() print(user2)
结果如下:
姓名:田大坑 年龄:24
修改数据update()
models.User.objects.filter(pk=1).update(name='张三疯', age=19)
删除数据delete()
models.User.objects.filter(pk=1).delete()
发现第一条数据被删除
五、单表查询
1、筛选数据filter
返回值是一个Queryset(可以看成是列表套数据对象)
筛选所有数据
user1 = models.User.objects.filter() print(user1)
结果:
<QuerySet [<User: 姓名:李思 年龄:20>, <User: 姓名:王思聪 年龄:22>, <User: 姓名:赵龙 年龄:23>, <User: 姓名:田大坑 年龄:24>]>
筛选具体数据
user1 = models.User.objects.filter(name='李思') print(user1)
结果:
<QuerySet [<User: 姓名:李思 年龄:20>]>
2、查询所有数据all()
返回值是一个Queryset(可以看成是列表套数据对象)
user1 = models.User.objects.all() print(user1)
结果:
<QuerySet [<User: 姓名:李思 年龄:20>, <User: 姓名:王思聪 年龄:22>, <User: 姓名:赵龙 年龄:23>, <User: 姓名:田大坑 年龄:24>]>
3、获取Queryset中第一个数据对象first()
user1 = models.User.objects.all().first() print(user1)
结果:
姓名:李思 年龄:20
如果为空则返回None
user1 = models.User.objects.filter(name="成龙").first() print(user1)
结果: None
4、获取Queryset中最后一个数据对象last()
user1 = models.User.objects.all().last() print(user1)
结果:
姓名:田大坑 年龄:24
如果为空则返回None
user1 = models.User.objects.filter(age=26).last() print(user1)
结果:None
5、直接根据条件查询具体的数据对象get()(不推荐使用)
user1 = models.User.objects.get(name="李思") print(user1)
结果:
姓名:李思 年龄:20
但是条件不存在则直接报错
user1 = models.User.objects.get(name="rose") print(user1)
结果:
6、指定查询字段values()
结果是Queryset(可以看成是列表套字典数据)
查询所有
obj = models.User.objects.values() print(obj)
结果:
<QuerySet [{'uid': 2, 'name': '李思', 'age': 20, 'join_time': datetime.date(2024, 12, 27)},
{'uid': 3, 'name': '王思聪', 'age': 22, 'join_time': datetime.date(2024, 12, 27)},
{'uid': 4, 'name': '赵龙', 'age': 23, 'join_time': datetime.date(2024, 12, 27)},
{'uid': 5, 'name': '田大坑', 'age': 24, 'join_time': datetime.date(2024, 12, 27)}]>
指定查询字段
obj = models.User.objects.values('name') print(obj)
结果:
<QuerySet [{'name': '李思'}, {'name': '王思聪'}, {'name': '赵龙'}, {'name': '田大坑'}]>
7、指定查询字段values_list()
结果是Queryset(可以看成是列表套元组)
obj = models.User.objects.values_list('name','age') print(obj)
结果:
<QuerySet [('李思', 20), ('王思聪', 22), ('赵龙', 23), ('田大坑', 24)]>
8、只当字段排序oeder_by()
结果是Queryset,默认是升序,在字段前加符号则为降序,并且支持多个字段排序
obj = models.User.objects.order_by('age') # 升序 print(obj)
结果:
<QuerySet [<User: 姓名:李思 年龄:20>, <User: 姓名:王思聪 年龄:22>, <User: 姓名:赵龙 年龄:23>, <User: 姓名:田大坑 年龄:24>]>
降序
obj = models.User.objects.order_by('-age') # 降序 print(obj)
结果:
<QuerySet [<User: 姓名:田大坑 年龄:24>, <User: 姓名:赵龙 年龄:23>, <User: 姓名:王思聪 年龄:22>, <User: 姓名:李思 年龄:20>]>
9、统计orm查询之后结果集中的数据数量count()
obj = models.User.objects.all().count() print(obj)
结果:4
10、针对重复的数据进行去重distinct()
去重的数据必须所有的数据都一样才符合去重,注意数据对象的主键
obj = models.User.objects.all().distinct() print(obj)
结果:
<QuerySet [<User: 姓名:李思 年龄:20>, <User: 姓名:王思聪 年龄:22>, <User: 姓名:赵龙 年龄:23>, <User: 姓名:田大坑 年龄:24>]>
11、针对括号内的条件取反进行数据査询exclude()
结果是Queryset(可以看成是列表套数据对象)
obj = models.User.objects.all().exclude(pk=2) print(obj)
结果:
<QuerySet [<User: 姓名:王思聪 年龄:22>, <User: 姓名:赵龙 年龄:23>, <User: 姓名:田大坑 年龄:24>]>
12、反转reverse()
只针对已经排过序的结果做反转
obj = models.User.objects.order_by('age').reverse() print(obj)
结果:
<QuerySet [<User: 姓名:田大坑 年龄:24>, <User: 姓名:赵龙 年龄:23>, <User: 姓名:王思聪 年龄:22>, <User: 姓名:李思 年龄:20>]>
13、执行SQL语句,还可以借助模块raw()
obj = models.User.objects.raw('select * from user') for item in obj: print("姓名 %s 年龄%d"%(item.name,item.age))
结果:
姓名 李思 年龄20 姓名 王思聪 年龄22 姓名 赵龙 年龄23 姓名 田大坑 年龄24
14、比较运算符查询
(1)、大于,字段名__gt
obj = models.User.objects.filter(age__gt=22) print(obj)
结果:
<QuerySet [<User: 姓名:赵龙 年龄:23>, <User: 姓名:田大坑 年龄:24>]>
(2)、小于,字段名__lt
obj = models.User.objects.filter(age__lt=22) print(obj)
结果:
<QuerySet [<User: 姓名:李思 年龄:20>]>
(3)、大于等于,字段名__gte
obj = models.User.objects.filter(age__gte=22) print(obj)
结果:
<QuerySet [<User: 姓名:王思聪 年龄:22>, <User: 姓名:赵龙 年龄:23>, <User: 姓名:田大坑 年龄:24>]>
(4)、小于等于,字段名__lte
obj = models.User.objects.filter(age__lte=22) print(obj)
结果:
<QuerySet [<User: 姓名:李思 年龄:20>, <User: 姓名:王思聪 年龄:22>]>
15、成员运算,字段名__in
obj = models.User.objects.filter(name__in=('李思','王思聪')) print(obj)
结果:
<QuerySet [<User: 姓名:李思 年龄:20>, <User: 姓名:王思聪 年龄:22>]>
16、范围查询,字段名__range
obj = models.User.objects.filter(age__range=(22,24)) print(obj)
结果:
<QuerySet [<User: 姓名:王思聪 年龄:22>, <User: 姓名:赵龙 年龄:23>, <User: 姓名:田大坑 年龄:24>]>
17、模糊查询
(1)、字段__contains(不忽略大小写)
obj = models.User.objects.filter(name__contains='李') print(obj)
结果:
<QuerySet [<User: 姓名:李思 年龄:20>]>
(2)、字段 icontains(忽略大小写)
models.User.objects.create(name='Rose', age=25) obj = models.User.objects.filter(name__icontains='rose') print(obj)
结果:
<QuerySet [<User: 姓名:Rose 年龄:25>]>
18、日期处理,字段__year、__mouth、__day
obj = models.User.objects.filter(join_time__year=2024) print(obj)
结果:
<QuerySet [<User: 姓名:李思 年龄:20>,
<User: 姓名:王思聪 年龄:22>,
<User: 姓名:赵龙 年龄:23>,
<User: 姓名:田大坑 年龄:24>,
<User: 姓名:Rose 年龄:25>]>
19、链式查询
users = models.User.objects.filter(name='赵龙').exclude(age__lt=22).filter(join_time=date(2024,12,27)).all() print(users)
等价于
qt = models.User.objects.filter(name='赵龙') qt = qt.exclude(age__lt=22) qt = qt.filter(join_time=date(2024,12,27)) print(qt)
20、Q查询
Q对象(django.db.models.Q)可以对关键字参数进行封装,从而更好地应用多个査询。可以组合使用 &(and),| (or),~(not)操作符,当一个操作符是用于两个Q的对象,它产生一个新的Q对象
每个接受关键字参数的査询函数(例如filter()、exclude()、get())都可以传递一个或多个Q 对象作为位置(不带名的)参数。如果一个查询函数有多个Q 对象参数,这些参数的逻辑关系为“AND"
users = models.User.objects.filter(Q(name='赵龙') & Q(age__gt=22) & Q(join_time=date(2024,12,27))) print(users)
结果:
<QuerySet [<User: 姓名:赵龙 年龄:23>]>
21、F查询
允许Diango在未实际链接数据的情况下具有对数据库字段的值的引用。通常情况下我们在更新数据时需要先从数据库里将原数据取出后方在内存里,然后编辑某些属性,最后提交。F对象支持四则运算
models.User.objects.update(age=F('age')+1)
所有的age的值都加1
22、bulk_create(objs,batch_size)批量插入
objs 批量插入的对象, batch size 缓存多少 如果不设置,batch size是objs的长度
user1 = models.User() user1.name = "刘志宝" user1.age = 24 user2 = models.User() user2.name = "林国瑞" user2.age = 34 user_list = [user1, user2] models.User.objects.bulk_create(user_list)
23、分组函数annotate()
用于实现聚合group by查询 前面的values写的是谁,就group谁
res = models.User.objects.values("join_time").annotate(age=Count('age')) print(res)
结果:
<QuerySet [{'join_time': datetime.date(2024, 12, 27), 'age': 5}, {'join_time': datetime.date(2024, 12, 30), 'age': 2}]>
24、聚合函数Avg,Mix,Max,Count,Sum
res = models.User.objects.aggregate(age=Sum('age')) print(res)
结果:
{'age': 177}
六、多表查询
分别创建publish、book、author、authorDetail四个模块,放入apps中。
注册:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'user', 'publish', 'book', 'author', 'authorDetail' ]
创建实体类
注意要指定表明,有外键的要指定外键名,否则表明和外键名会生成任意的名字。
Publish
class Publish(models.Model): pid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) email = models.CharField(max_length=32) class Meta: managed = True db_table = "publish" verbose_name = "出版社信息" verbose_name_plural = verbose_name def __str__(self): return "出版社:%s"%self.name
Book
from author.models import Author from publish.models import Publish # Create your models here. class Book(models.Model): bid = models.AutoField(primary_key=True) title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8, decimal_places=2) publish_time = models.DateTimeField(auto_now=True) publish = models.ForeignKey(Publish, on_delete=models.CASCADE) author = models.ManyToManyField(Author) class Meta: managed = True db_table = "book" verbose_name = "书籍信息" verbose_name_plural = verbose_name def __str__(self): return "书籍:%s"% self.title
一对多关系表数据操作,书籍与出版社的关系,一个出版社对应多本书籍,ORM中外键字段建在多的一方 models.Foreignkey()
publish = models.ForeignKey(Publish, on_delete=models.CASCADE,db_column="publish_id")
_id后级无需添加会自动添加上
多对多
ORM中有三种创建多对多字段的方式,models.ManyToManyField()
1.直接在查询频率较高的表中填写字段即可,自动创建第三张表关系
2.自己创建第三张关系表
3.自己创建第三张关系表,但还是要orm多对多字段做关联
Author
from authorDetail.models import AuthorDetail # Create your models here. class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() author_detail = models.OneToOneField(AuthorDetail, on_delete=models.CASCADE) class Meta: managed = True db_table = "author" verbose_name = "作者信息" verbose_name_plural = verbose_name def __str__(self): return "作者:%s" % self.name
一对一关系表数据操作:ORM中外键字段建在查询频率较高的表中 models.OneToOneField()
author_detail = models.OneToOneField(AuthorDetail, on_delete=models.CASCADE,db_column='author_detail_id')
_id后缀无需添加,会自动添加上
AuthorDetail
class AuthorDetail(models.Model): phone = models.BigIntegerField() addr = models.CharField(max_length=225) class Meta: managed = True db_table = "author_detail" verbose_name = "作者详情信息" verbose_name_plural = verbose_name def __str__(self): return "地址:%s"% self.addr
用以下两个命令将类映射到表
python manage.py makemigrations python manage.py migrate
生成的表如下:
publish表的建表语句为:
CREATE TABLE `publish` ( `pid` int(0) NOT NULL AUTO_INCREMENT, `name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `email` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`pid`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
book表的建表语句为:
CREATE TABLE `book` ( `bid` int(0) NOT NULL AUTO_INCREMENT, `title` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `price` decimal(8, 2) NOT NULL, `publish_time` datetime(6) NOT NULL, `publish_id` int(0) NOT NULL, PRIMARY KEY (`bid`) USING BTREE, INDEX `book_publish_id_74897046_fk_publish_pid`(`publish_id`) USING BTREE, CONSTRAINT `book_publish_id_74897046_fk_publish_pid` FOREIGN KEY (`publish_id`) REFERENCES `publish` (`pid`) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
author表的建表语句为:
CREATE TABLE `author` ( `id` bigint(0) NOT NULL AUTO_INCREMENT, `name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `age` int(0) NOT NULL, `author_detail_id` bigint(0) NOT NULL, PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `author_detail_id`(`author_detail_id`) USING BTREE, CONSTRAINT `author_author_detail_id_f363802f_fk_author_detail_id` FOREIGN KEY (`author_detail_id`) REFERENCES `author_detail` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
book表与author表的关联表book_author
CREATE TABLE `book_author` ( `id` bigint(0) NOT NULL AUTO_INCREMENT, `book_id` int(0) NOT NULL, `author_id` bigint(0) NOT NULL, PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `book_authors_book_id_author_id_96c38d5f_uniq`(`book_id`, `author_id`) USING BTREE, INDEX `book_authors_author_id_ea39dbe4_fk_author_id`(`author_id`) USING BTREE, CONSTRAINT `book_authors_author_id_ea39dbe4_fk_author_id` FOREIGN KEY (`author_id`) REFERENCES `author` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT, CONSTRAINT `book_authors_book_id_a678937d_fk_book_bid` FOREIGN KEY (`book_id`) REFERENCES `book` (`bid`) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
author_detail表的建表语句:
CREATE TABLE `author_detail` ( `id` bigint(0) NOT NULL AUTO_INCREMENT, `phone` bigint(0) NOT NULL, `addr` varchar(225) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
外键字段数据操作:
一对多关系表数据操作
(1)、先创建没有外键字段的表数据,出版社表;
models.Publish.objects.create(name="科学出版社",email="mph@mail.sciencep.com")
(2)、再创建有外键字段的表数据,书籍表
方式1,直接给实际字段添加关联数据值 publishid=1
models.Book.objects.create(title="高等数学",price="55",publish_id=1)
方式2,间接使用外键虚拟字段添加数据对象 publish=publish_obj
publish_obj = models.Publish.objects.filter(pk=2).first() models.Book.objects.create(title="汉奸养成记", price="5", publish=publish_obj)
一对一关系表数据操作:
(1)、先创建没有外键字段的表数据,作者详情表
models.AuthorDetail.objects.create(phone="15345678909",addr="上海闵行区")
(2)、在创建有外键字段的作者表数据,作者表
方式1 直接给实际字段添加关联数据值author detailid=1
models.Author.objects.create(name="张三",age=22,author_detail_id=1)
方式2 间接使用外键虚拟字段添加数据对象 author_detail=authorDetail_obj
author_detail_obj = models.AuthorDetail.objects.filter(pk=2).first() models.Author.objects.create(name="李思", age=23, author_detail=author_detail_obj)
多对多关系表数据操作
author = models.ManyToManyField(Author)
1.add添加数据,括号内即可填写数字值也可以填写数据对象,支持多个
方式1,直接添加id值
book_obj = models.Book.objects.filter(pk=2).first() book_obj.author.add(1)
此时book_author表添加一条记录
book_obj = models.Book.objects.filter(pk=2).first() book_obj.author.add(2,3)
此时book_author表增加两条记录
方式2,添加作者对象
book_obj = models.Book.objects.filter(pk=3).first() author_obj = models.Author.objects.filter(pk=1).first() book_obj.author.add(author_obj)
结果新增一条数据
book_obj = models.Book.objects.filter(pk=3).first() author_obj1 = models.Author.objects.filter(pk=2).first() author_obj2 = models.Author.objects.filter(pk=3).first() book_obj.author.add(author_obj1) book_obj.author.add(author_obj2)
结果新增两条数据
2.remove删除数据,阔号内可以填写数字值也可以填写数据对象,支持多个
book_obj = models.Book.objects.filter(pk=3).first() book_obj.author.remove(2,3)
此时book_id为3,author_id为2/3的记录删除
正反向概念
正反向概念核心就在于外键字段在谁手上
正向查询:通过书查询出版社,外键字段在书表中
反向查询:通过出版社查询书,外键字段不在出版社表中
ORM跨表查询口诀>>>:正向查询按外键字段,反向查询按表名小写
基于对象的跨表查询(子查询)
基于对象的正向跨表查询
1.查询主键为2的书籍对应的出版社(书>>>出版社)
book_obj = models.Book.objects.filter(pk=2).first() print(book_obj.publish)
书査出版社 外键字段在书表中 所以是正向査询 正向按外键字段.外键字段为pulish
2.查询主键为3的书籍对应的作者(书 >>>作者)
book_obj = models.Book.objects.filter(pk=3).first() print(book_obj.author.all())
书查作者,外键字段在书表中 所以是正向査询 正向按外键字段.Book类的外键字段为author
3、查询李思的作者详情
author_obj = models.Author.objects.filter(name='李思').first() print(author_obj.author_detail)
作者査作者详情,外键字段在作者表中,所以是正向査询,正向査询按外键字段
基于对象的反向跨表查询
1.查询清华大学出版社出版的书籍
publish_obj = models.Publish.objects.filter(name='清华大学出版社').first() print(publish_obj.book_set.all())
出版社査书籍,外键字段在书籍表中,所以是反向査询 反向查询按表名小写
2、查询李思写过的书
author_obj = models.Author.objects.filter(name='李思').first() print(author_obj.book_set.all())
作者査书籍,外键字段在书籍表中,所以是反向査询,反向查询按表名小写
3、查询电话是15342234567的作者
detail_obj = models.AuthorDetail.objects.filter(phone='15342234567').first() print(detail_obj.author)
作者详情査作者,外键字段在作者表中,是反向査询,反向查询按表名小写
基于双下划线的跨表查询(连表操作)
基于双下划线的正向跨表查询
1.查询主键为2的书籍对应的出版社名称及书名
res = models.Book.objects.filter(pk=2).values("publish__name","title") print(res)
结果:
<QuerySet [{'publish__name': '清华大学出版社', 'title': '汉奸养成记'}]>
2.查询主键为3的书籍对应的作者姓名及书名
res = models.Book.objects.filter(pk=3).values("author__name","title") print(res)
结果:
<QuerySet [{'author__name': '王五', 'title': '数学'}]>
3、查询李思的作者的电话号码和地址
res = models.Author.objects.filter(name='李思').values("author_detail__addr","author_detail__phone") print(res)
结果:
<QuerySet [{'author_detail__addr': '武汉洪山区', 'author_detail__phone': 15345678910}]>
基于双下划线的反向跨表查询
1.查询清华大学出版社出版的书籍名称和价格
res = models.Publish.objects.filter(name="清华大学出版社").values("book__title","book__price") print(res)
结果:
<QuerySet [{'book__title': '汉奸养成记', 'book__price': Decimal('5.00')}]>
2、查询李思写过的书的名称和日期
res = models.Author.objects.filter(name="李思").values("book__title","book__publish_time") print(res)
结果:
<QuerySet [{'book__title': '汉奸养成记', 'book__publish_time': datetime.datetime(2024, 12, 27, 8, 43, 52, 695218, tzinfo=datetime.timezone.utc)}]>
3、查询电话是15342234567的作者姓名和年龄
res = models.AuthorDetail.objects.filter(phone="15342234567").values("author__name","author__age") print(res)
结果:
<QuerySet [{'author__name': '王五', 'author__age': 30}]>
4、查询主键为2的书籍对应的作者电话号码
res = models.Book.objects.filter(pk=3).values("author__author_detail__phone") print(res)
结果:
<QuerySet [{'author__author_detail__phone': 15342234567}]>
标签:__,obj,name,author,python,django,models,objects,mysql From: https://www.cnblogs.com/zwh0910/p/18634786