Django --- ORM

冷暖自知 提交于 2019-12-05 20:37:17

使用数据库之前的配置工作

settings.py中的配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'day53',
        'USER':'root',
        'PASSWORD':'123qwe',
        'HOST':'127.0.0.1',
        'PORT':3306,
        'CHARSET':'utf8'
    }}

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

init.py中的配置

import pymysql
pymysql.install_as_MySQLdb()

test.py中配置

import os

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")

    import django
    django.setup()
    from app01 import models   # 一定要写在下边

单表操作常用的方法

创建数据

# 1.create方法创建数据
book_obj = models.Books.objects.create(title='三国演义',price=123.23,publish_date='2019-11-11')

# 2.利用对象的绑定方法
book_obj = models.Books(title='西游记',price=666.66,publish_date='2000-1-21')
book_obj.save()

修改数据

# 方式1  利用queryset方法
models.Books.objects.filter(pk=1).update(price=444.66)

# 方式2  利用对象
book_obj = models.Books.objects.get(pk=1)
book_obj.price = 222.66
book_obj.save() 

# pk会自动帮你找到当前的主键字段,所以会经常使用pk来指代主键字段;

filter查询

filter查询出来的结果是一个Queryset对象

1.只要是queryset对象就可以无限制的调用queryset的方法

2.只要是queryset对象就可以点query查看当前结果内部对应的sql语句

get和filter的区别

1.filter获取到的是一个queryset对象,类似于一个列表

2.get获取到的直接就是数据对象本身

3.当条件不存在的时候,filter直接返回一个空,而get会直接报错,所以推荐使用filter

删除数据

# 1.利用queryset方法 delete()
models.Books.objects.filter(pk=3).delete()

# 2,对象方法
book_obj = models.Books.objects.get(pk=3)
book_obj.delete()

查数据13条

1.查所有 all()

res = models.Books.objects.all()   # 返回结果Queryset对象,是列表套对象的行式

2.筛选 filter()

res = models.Books.objects.filter(pk=1,title='三')   # 支持多个参数,并且是and关系,不能模糊刷选

3.筛选 get()

res = models.Books.objects.get(title='西游记')   # 获取的是数据对象本身,条件不存在的时候会直接报错,并且查询条件必须是唯一

4.取queryset中第一个数据对象 first()

res = models.Books.objects.filter(title='西游记').first()

5.取queryset中最后一个对象 last()

res = models.Books.objects.filter(title='西游记').last()

6.统计数据的个数 count()

num = models.Books.objects.count()   # 不需要传入参数

7.获取数据对象中指定的字段的值 values()

res = models.Books.objects.values('title','price')  
# 可以有多个,格式是列表套字典  

8.获取数据对象中指定的字段的值 values_list()

res = models.Books.objects.values_list('title','price')    
# 可以有多个,格式是列表套元组     <QuerySet [('西游记',), ('水浒传',), ('红楼梦',)]>

9.按照指定的字段排序 order_by()

res = models.Books.objects.order_by('price')
res1 = models.Books.objects.all().order_by('price')
# 默认是升序,两者等价,下边的语义更明确

#倒序
res1 = models.Books.objects.all().order_by('-price')

10.颠倒顺序 reverse()

res3 = models.Books.objects.all().order_by('price').reverse()
# 前提是颠倒的对象必须有顺序,(提前排序之后才能颠倒)

11.排除对象 exclude()

res = models.Books.objects.all().exclude(title='三国演义')
# <QuerySet [<Books: 红楼梦>, <Books: 西游记1>, <Books: 西游记2>]>

12.判断查询结果是否有值 exists()

res = models.Books.objects.filter(pk=1).exists()  
# 返回时布尔值,但是数据本身就带有布尔值,所以一般不需要使用

13.对查询结果进行去重操作 distinct()

res = models.Books.objects.values('title','price').distinct()
# 去重的前提时数据必须时完全一样的情况下才能够去重,容易忽略的时主键

神奇的下划线方法

查询价格大于X的值

res = models.Books.objects.filter(price__gt=500)

查询价格小于X的值

res = models.Books.objects.filter(price__lt=400)

查询价格大于等于X的值

res = models.Books.objects.filter(price__gte=500)
# 使用数字是小数的时候会查询不到等于的情况

查询小于等于X的值

res = models.Books.objects.filter(price__lte=500)

查询自定义区间内的值

 res = models.Books.objects.filter(price__in=[222,444,500])

查询在某区间内的值

res = models.Books.objects.filter(price__range=(200,800))  # 顾头顾尾

查询出版日期是某年的值

res = models.Books.objects.filter(publish_date__year='2019')

查询出版日期是1月份的值

res = models.Books.objects.filter(publish_date__month='1')
# 只按照月份筛选,对年份没有要求

查询是以什么开头的值

res = models.Books.objects.filter(title__startswith='三')

查询是以什么结尾的值

res = models.Books.objects.filter(title__endswith='1')

查询值包含某个字段的值

res = models.Books.objects.filter(title__contains='p')  # 默认区分大小写
res = models.Books.objects.filter(title__icontains='p')  # 忽略大小写 加i

一对多字段的增删改查

# 第一种
models.Book.objects.create(title='三国演义',price=222.33,publish_id=1)

# 第二种
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title='红楼梦',price=444.33,publish=publish_obj) 

# 第一种
models.Book.objects.filter(pk=1).update(publish_id=2)

# 第二种
publish_obj = models.Publish.objects.filter(pk=1).first()
models.Book.objects.filter(pk=1).update(publish=publish_obj)

models.Publish.objects.filter(pk=1).delete()  # 默认就是级联删除 级联更新

多对多字段数据的增删改查

# 给一本书添加作者
# 第一种
book_obj = models.Book.objects.filter(pk=2).first()
book_obj.author.add(5)  # 添加一个
book_obj.author.add(3,5)  # 添加多个

# 第二种
author_obj = models.Author.objects.filter(pk=1).first()
book_obj.author.add(author_obj)

#总结
add方法:能够朝第三张表中添加数据,支持添加数据也支持添加对象,

# 更改一本书的作者
# 第一种
book_obj = models.Book.objects.filter(pk=2).first()
book_obj.author.set((1,3))  # 必须是可迭代对象

# 第二种
book_obj = models.Book.objects.filter(pk=2).first()
author_obj = models.Author.objects.filter(pk=1).first()
book_obj.author.set((author_obj,))   # 不许是可迭代对象

#总结
set方法:set方法既可以按照数字进行设置,也可以按照对象进行设置,可以传入多个值,但是传入的参数必须是可迭代对象。

# 删除书的作者
# 第一种方法
book_obj = models.Book.objects.filter(pk=2).first()
book_obj.authors.remove(1,2)

# 第二种方法
author_obj = models.Author.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=2).first()
book_obj.authors.remove(author_obj,author_obj1)

#总结
remove方法:可以删除一个,也可以删除多个,并且不需要迭代,

清空

删除某个数据在第三张表中的所有数据

book_obj = models.Book.objects.filter(pk=2).first()
book_obj.author.clear()

# clear清空所有的相关记录,括号内不需要传递参数

跨表查询

注意:关系字段在谁那里,由谁查谁就是正向,如果没有关系字段,就是反向查询

基于对象跨表查询——正向查询

正向查询按字段,反向查询按表名小写+_set

# 查询书id为2的书的出版社名
# 第一种 --- 正向查询
book_obj = models.Book.objects.filter(pk=2).first()
print(book_obj.publish)

# 第二种 --- 上下划线查询
publish_obj = models.Publish.objects.filter(book__pk=2).first()
print(publish_obj.publish_name)

基于双下划线跨表查询

正向查询按字段,反向查询按表名小写+_set

# 查询作者'wang'写了哪些书
author_obj = models.Author.objects.filter(username='wang').first()
print(author_obj.book_set.all())
正向查询的时候,根据已有的主键,铜通过对象.主键的方式可以进入外键所在的表中,此时形成的是外键所在表的对象,根据对象.属性来进行查询需要的内容
authorbook
'__':__使用的时候是基于外键所在的表为查询对象,查询条件为 "表名小写__pk=2"  数字为需要查询的内容的id号,可以通过 " __ " 来使用外键所在的id,使用"__" 的前提是两张表之间使用外键进行关联过。不能没有外键关联使用这种方法
    
" 表名小写_set ":用book与author的表为例,author与book两张表的键在book中,所以查数对应的作者很简单,但是查作者对应的数就没有办法通过键来进行查询,此时使用 "book_set" 就相当于在author中使用了连接键。

什么时候添加.all()

当查询出来的结果为多个的时候使用 .all() 来进行接收,会有提示的报错 app01.Author.None

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!