首页 > 其他分享 >django框架(六)

django框架(六)

时间:2022-12-18 14:44:41浏览次数:32  
标签:__ 框架 author models res django filter objects

ORM执行SQL语句

有时候ORM的操作效率可能偏低,其实也支持自己写SQL语句

#方式1:
#注意表名
    res = models.User.objects.raw('select * from app01_user where id<3;')
    print(list(res))
    """
    [<User: 用户对象:jason>, <User: 用户对象:torry>]
    """

image

#方式2:
    from django.db import connection
    cursor = connection.cursor()
    cursor.execute('select name from app01_user where id<4;')
    
    # print(cursor.fetchall())
    """
    (('jason',), ('torry',), ('kevin',))
    """
    print(cursor.fetchone())
    print(cursor.fetchone())
    """
    ('jason',)
    ('torry',)
    """

image

神奇的双下划线查询

以下直接打印res返回的结果是QuerySet数据对象

只要还是queryset对象,就可以无限制的去点queryset对象的方法

(1)比较运算符
字段__gt     # 大于
字段__gte    # 大于等于
字段__lt     # 小于
字段__lte    # 小于等于
#查询年龄大于18的数据
res = models.User.objects.filter(age__gt=18)
#查询年龄大于等于18的数据
res = models.User.objects.filter(age__gte=18)
(2)成员运算
字段__in=()   # 在某几个数据中 可以给多个值
#查询年龄是18、28、38的数据
res = models.User.objects.filter(age__in=(18,28,38))
(3)范围查询
字段__range=[]    # 在某个范围内 最多给两个值
#查询年龄在10~20之间的数据(包含10和20)
res = models.User.objects.filter(age__range=(10,20))
(4)模糊查询
字段__contains   # 区分大小写
字段__icontains  # 不区分大小写
#查询姓名中有字母j的数据
res = models.User.objects.filter(name__contains='j')
(5)日期处理

需注意settings.py中时间为UTC时间,所以月和日不准。后面BBS项目再改

字段__year     # 年
字段__month    # 月
字段__day      # 日
#查询注册年份是2022的数据
res = models.User.objects.filter(register_time__year=2022)

ORM外键字段的创建

"""
复习MySQL外键关系
    一对多
        外键字段建在多的一边
    多对多
        外键字段键在第三张关系表中
    一对一
        外键字段键在查询频率较高的表中
"""
(1)前期准备
1.cmd中创建库
create database 库名;

2.settings.py配置文件中把库sqlite3改为mysql
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'day06', # 库名
        'USER': 'root',
        'PASSWORD': '123',
        'HOST': '127.0.0.1',
        'PORT': 3306,
        'CHARSET': 'utf8'}
创建模型类补充知识
#小数字段:
DecimalField        #小数

#小数字段参数:
max_digits=8      #总共8位
decimal_places=2  #小数点后占2位
————————————————————————————————————————
创建完表后建议用"""图书表"""标注一下
————————————————————————————————————————
3.模型层models.py中写入模型类(写4张表)

class Book(models.Model):
    """图书表"""
    title = models.CharField(max_length=32, verbose_name='书名')
    price = models.DecimalField(max_digits=8, decimal_places=2, verbose_name='价格')
    publish_time = models.DateField(auto_now_add=True, verbose_name='出版日期')


class Publish(models.Model):
    """出版社表"""
    name = models.CharField(max_length=32, verbose_name='出版社名字')
    address = models.CharField(max_length=64, verbose_name='地址')


class Author(models.Model):
    """作者表"""
    name = models.CharField(max_length=32, verbose_name='作者')
    age = models.IntegerField(verbose_name='年龄')


class AuthorDetail(models.Model):
    """作者详情表"""
    phone = models.BigIntegerField(verbose_name='手机号')
    address = models.CharField(max_length=64, verbose_name='家庭住址')
4.分析四张表的表关系 确定外键字段建在哪里
#  图书表   与   出版社表
     一本书对应多个出版社  ×
     一个出版社对应多本书  √
     一对多,书为多,外键在多(书)
    #ForeignKey
————————————————————————————————    
#  图书表   与   作者表
     一本书对应多个作者  √
     一个作者对应多本书  √
     多对多,书频率高,外键在书
    '需有绑定两个表关系的第三张表'
    #ManyToManyField
————————————————————————————————
#  作者表   与   作者详情表
    一个作者对应多个作者详情  ×
    一个作者详情对应多个作者  ×
    一对一,作者频率高,外键在作者
    #OneToOneField
创建外键字段补充知识
一对多、一对一会给外键字段名自动加一个_id后缀`
 `多对多不会只是虚拟字段,不会在表中显示,会去创建第三张表
#创建一对多外键字段
publish = models.ForeignKey(to='关联的类名(表)',on_delete=models.CASCADE)
"""
ORM在表中会自动给publish加一个_id后缀用来表示是该表的外键
on_delete=models.CASCADE  级联删除

django1.X版本所有外键字段默认都是级联更新级联删除
django2.X版本及以上需自己声明
"""
————————————————————————————————————————————————

#创建多对多外键字段
author = models.ManyToManyField(to='关联的类名(表)')
"""

多对多外键字段为虚拟字段,表中看不到该字段。用来告诉ORM自动创建第三张表
多对多不需要声明级联更新级联删除

    ORM比SQL有更多优化
    1.外键字段可以在某张表中(查询频率最高的)
       内部会自动创建第三张表关系 (表名:app01_表1_表2)
    2.自己创建第三张关系表,并自己创建两个外键字段
       其实也可以写外键,后续会了解
      PS:暂不考虑第二种方式
"""
——————————————————————————————————————————
#创建一对一外键字段
author_detail=models.OneToOneField(to='关联的类名(表)',on_delete=models.CASCADE)
"""
ORM在表中会自动给author_detail加一个_id后缀用来表示是该表的外键
on_delete=models.CASCADE  级联删除

django1.X版本所有外键字段默认都是级联更新级联删除
django2.X版本及以上需自己声明
"""
5.给需要的表添加外键字段
#【Book图书表】:

# 创建书籍与出版社的一对多外键字段
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
# 创建书籍与作者表的多对多外键字段
author = models.ManyToManyField(to='Author')
——————————————————————————————————————————————
#【Author作者表】:

# 创建作者与作者详情表的一对一外键字段
author_detail=models.OneToOneField(to='AuthorDetail',on_delete=models.CASCADE)
6.写完模型类后执行数据库迁移命令
    python38 manage.py makemigrations
    python38 manage.py migrate

外键字段数据的增改删

(1)前期准备

1.先给三张表提前录入需要的数据 图书表、图书与作者关系的第三张表用orm操作

#【app01_authordetail作者详情表】
录入数据
#【app01_author作者表】
录入数据
#【app01_publish出版社表】
录入数据

2.搭建测试环境

import os
import sys

def main():
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoday06.settings')
    import django
    django.setup()
(2)增
①一对一和一对多

create()

给图书表app01_book增数据

1.#可直接填写表中的字段名添加主键
models.Book.objects.create(title='三国演义',price=88.88,publish_id=1)

2.#也可填写对应的对象
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title='水浒传',price=66.66,publish=publish_obj)

image

②多对多

add()

给 书跟作者的第三张关系表app01_book_author增数据

由于给某张表中添加数据需要用models去点一个表,发现自动创建的第三张关系表没办法点出来。所以就要想其他办法:需要获取一个含有多对多关系字段的数据对象即可(书籍表中有一个authors虚拟字段,所以获取书籍对象即可)

1.#找到含有多对多关系字段的对象 然后在第三张表中绑定关系
book_obj=models.Book.objects.filter(pk=1).first()#找到id=1的书籍对象
book_obj.author.add(1) #在第三张关系表中给该书籍对象绑定作者id
book_obj.author.add(2,3)#且支持绑定多个作者id

2.#也可以填写作者对象
book_obj=models.Book.objects.filter(pk=2).first()#找到id=2的书籍对象
author_obj1=models.Author.objects.filter(pk=1).first()#找id=1的作者对象
author_obj2=models.Author.objects.filter(pk=2).first()#找id=2的作者对象
book_obj.author.add(author_obj1,author_obj2)#在第三张表中给该书籍对象绑定作者对象

"""
orm会自动识别对象或id绑定
"""

image

(3)改
注意:set([])中必须跟列表或元组
①多对多

set([])或set(())修改

1.#找到要修改外键绑定关系的书籍对象 然后在第三张表中修改关系
book_obj=models.Book.objects.filter(pk=1).first()#找到对应id的书籍对象
book_obj.author.set([1,])#在第三章表中修改绑定关系
"""
注意:如果没有该关系则是先删除再新增
"""

2.#也可以填写作者对象
book_obj=models.Book.objects.filter(pk=2).first()#找到对应id的书籍对象
author_obj=models.Author.objects.filter(pk=3).first()#找到对应id的作者对象
book_obj.author.set([author_obj])#在第三章表中修改绑定关系

image

(4)删
①多对多

remove()
clear()清空

1.#找到要删除绑定关系的书籍对象 然后在第三张表中修改关系
book_obj=models.Book.objects.filter(pk=1).first()
book_obj.author.remove(2,3)#在第三章表中修改绑定关系

2.#也可以填写作者对象
book_obj=models.Book.objects.filter(pk=2).first()
author_obj=models.Author.objects.filter(pk=3).first()
book_obj.author.remove(author_obj)

3.#直接把某本书的所有关系清空
book_obj=models.Book.objects.filter(pk=2).first()
book_obj.author.clear()

8)ORM跨表查询

"""
复习MySQL跨表查询
    子查询
        分步操作:将一条SQL语句用括号括起来当作另外一条SQL语句的条件
    连表操作
        先整合多张表之后基于单表查询
        inner join  内连接
        left join   左连接
        right join  右连接
"""
正反向查询的概念(重要)
#正向查询
    由外键字段所在的表数据查询关联的表数据 正向
    '通过书查询出版社 外键字段在书表中'
#反向查询
    没有外键字段的表数据查询关联的表数据	 反向
    '通过出版社查询书 外键字段不在出版社表中'
    
#ps:正反向的核心就看外键字段在不在当前数据所在的表中
 
"""
ORM跨表查询的口诀:
	正向查询按外键字段     (模型类里写的外键字段)
	反向查询按表名小写_set (当结果可能是多的时候用_set.all(),单个时不用加)
"""
(1)基于对象的跨表查询
'''基于对象的正向跨表查询'''
1.查询主键为1的书籍对应的出版社名称
    # 先根据条件获取数据对象
    book_obj = models.Book.objects.filter(pk=1).first()
    # 再判断正反向的概念  由书查出版社 外键字段在书所在的表中 所以是正向查询
    # print(book_obj.publish) # Publish object (1)
    print(book_obj.publish.name) # 北方出版社

2.查询主键为1的书籍对应的作者姓名
    # 先根据条件获取数据对象
    book_obj = models.Book.objects.filter(pk=1).first()
    # 再判断正反向的概念  由书查作者 外键字段在书所在的表中 所以是正向查询
    # print(book_obj.authors)  # app01.Author.None
    # print(book_obj.authors.all())
    # <QuerySet [<Author: Author object (1)>, <Author: Author object (2)>]>
    # 如果在模型表modles.py中写了__str__方法 可打印出对象的名字
    print(book_obj.authors.all().values('name'))
    # <QuerySet [{'name': 'zy'}, {'name': 'mm'}]>
    
3.查询jason的电话号码
    author_obj = models.Author.objects.filter(name='jason').first()
    print(author_obj.author_detail.phone)

'''基于对象的反向跨表查询'''
4.查询北方出版社出版过的书籍
    # 先根据条件获取数据对象
    publish_obj = models.Publish.objects.filter(name='北方出版社').first()
    # 再判断正反向的概念  由出版社查书 外键字段在书所在的表中 所以是反向查询
    # print(publish_obj.book_set)  # app01.Book.None
    print(publish_obj.book_set.all().values('title'))

5.查询jason写过的书籍
    author_obj = models.Author.objects.filter(name='jason').first()
    # print(author_obj.book_set)  # app01.Book.None
    print(author_obj.book_set.all().values('title'))

6.查询电话号码是110的作者姓名
    authordetail_obj=models.AuthorDetail.objects.filter(phone=110).first()
    print(authordetail_obj.author.name)
(2)基于双下划线的跨表查询
'''基于双下划线的正向跨表查询'''
1.查询主键为1的书籍对应的该书籍名称和出版社名称
    # 先根据条件获取数据对象 然后判断书籍和出版社是正向查询 values里支持之反向__字段名获取值
    res=models.Book.objects.filter(pk=1).values('title','publish__name')
    print(res)
2.查询主键为3的书籍对应的该书籍名称和作者姓名
    res=models.Book.objects.filter(pk=3).values('title','author__name')
    print(res)
3.查询jason的电话号码
    res=models.Author.objects.filter(name='jason').values('author_detail__phone')
    print(res)

'''基于双下划线的反向跨表查询'''
4.查询北方出版社出版过的书籍名称和价格
    res=models.Publish.objects.filter(name='北方出版社').values('book__title','book__price')
    print(res)

5.查询jason写过的书籍名称
    res=models.Author.objects.filter(name='jason').values('book__title')
    print(res)

6.查询电话号码是110的作者姓名
    res=models.AuthorDetail.objects.filter(phone=110).values('author__name')
    print(res)
(3)进阶操作

如果不能用已知的条件去查,则需要用另一个已知去推,(原本正向变成了反向)

'''原本正向变反向'''
1.查询主键为1的书籍对应的出版社名称
	# 用第二张表里筛选中反向操作获取对象 然后values取自己表中的数据
    res=models.Publish.objects.filter(book__pk=1).values('name')
    print(res)
    
2.查询主键为3的书籍对应的作者姓名
    res=models.Author.objects.filter(book__pk=3).values('name')
    print(res)
    
3.查询jason的电话号码
    res=models.AuthorDetail.objects.filter(author__name='jason').values('phone')
    print(res)
    
'''原本反向变正向'''
4.查询北方出版社出版过的书籍名称和价格
    res=models.Book.objects.filter(publish__name='北方出版社').values('title','price')
    print(res)
    
5.查询jason写过的书籍名称
    res=models.Book.objects.filter(author__name='jason').values('title')
    print(res)
    
6.查询电话号码是110的作者姓名
    res=models.Author.objects.filter(author_detail__phone=110).values('name')
    print(res)
    



# 三表:查询主键为1的书籍对应的作者的电话号码
	#支持跨表查询,当查到作者表时,可继续点外键字段获取电话号
方法一:res=models.Book.objects.filter(pk=1).values('author__author_detail__phone')
        print(res)
    
方法二:res = models.AuthorDetail.objects.filter(author__book__pk=4).values('phone')
        print(res)
    
方法三:res = models.Author.objects.filter(book__pk=4).values('author_detail__phone')
        print(res)

标签:__,框架,author,models,res,django,filter,objects
From: https://www.cnblogs.com/lvqingmei/p/16990372.html

相关文章

  • django框架(部分讲解)
    图书管理系统讲解前期准备工作修改配置文件表设计考虑普通字段考虑外键字段数据库迁移连接数据库插入数据测试数据录入首页展示创建一个h......
  • Pytorch框架详解之一
    Pytorch基础操作numpy基础操作定义数组(一维与多维)寻找最大值维度上升与维度下降数组计算矩阵reshape矩阵维度转换代码实现importnumpyasnpa=np.array([......
  • 【Python自动化框架pytest(三)--数据驱动(参数化)】
    参数化,就是把测试过程中的数据提取出来,通过参数传递不同的数据来驱动用例运行。其实也就是数据驱动的概念。在Unittest中,我们讲过使用ddt库配合unittest实现数据驱动......
  • 【Python自动化框架pytest(四)--其他】
    一、pytest中的skip和xfailskip跳过测试函数skip意味着您希望只有在满足某些条件时测试才能通过,否则pytest应该跳过运行测试。常见的例子是跳过非Windows平台上的仅限Wind......
  • 框架第七课---图书管理系统详解
    ..homePage.html页面代码<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title>{#<scriptsrc="jQuery3.6.js"></scrip......
  • pytest + yaml 框架 -17.文件上传功能
    前言本插件集成了requests_toolbelt插件处理Content-Type:multipart/form-data类型文件上传接口。文件上传multipart/form-data用fiddler抓包,查看抓到的接口,以下这......
  • pytest框架
    在pytest框架中,有如下约束:所有的单测文件名都需要满足test_*.py格式或*_test.py格式。在单测文件中,测试类以Test开头,并且不能带有init方法(注意:定义class时,需要以T开头,......
  • 手撸web框架
    egon新书来袭请看:https://egonlin.com/book.html一Web应用的组成接下来我们学习的目的是为了开发一个Web应用程序,而Web应用程序是基于B/S架构的,其中B指的是浏览器,负责......
  • pytest + yaml 框架 -16.提供一个常用的内置函数和方法生成随机测试数据
    前言在测试的过程中经常会用到一些随机值,比如生成随机手机号,随机身份证,姓名等数据。内置方法目前暂时提供了3个内置函数,和1个内置对象current_time(f:str='%Y-%m-%......
  • 推荐几个精致的web UI框架及常用前端UI框架
    以下是几个精致的webUI框架1.AliceuiAliceui是支付宝的样式解决方案,是一套精选的基于spm生态圈的样式模块集合,是Arale的子集,也是一套模块化的样式命名和组织规范,是......