django模型层数据增删改查

模型层

如何配置测试脚本

# 第一种:
# 直接在某一个应用下的tests文件中书写下面内容(去manage.py拷贝前四行代码)然后自己写两行代码即可
import os


if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")
    import django
    django.setup()
                            
    # 一定要等待测试脚本搭建完毕之后 才能导入django文件进行测试
    from app01 import models
                    
# 第二种:
# 直接新建一个任意名称的py文件 在里面也写上面的配置 也可以配置
import os
if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")
    import django
    django.setup()
    # 一定要等待测试脚本搭建完毕之后 才能导入django文件进行测试
    from app01 import models

创建数据

# 第一种:create方法
book_obj=models.Book.objects.create(title='三国演义',price=22,publish_date='2019-1-1')

# 第二种:利用对象的绑定方法
book_obj=models.Booke(title='三国演义',price=22,publish_date='2019-1-1')
book_obj.save()

修改数据

res=models.Book.objects.filter(pk=1)    # pk:会自动帮你查找到当前表的主键字段
# filter:查询出来的结果事一个Queryset
# 注意:
#   1.只要是Queryset对象就可以无限制的调用queryset的方法
#   2.只要是queryset对象就可以点query查看当前结果内部对应的sql语句。如:res.query

# 方式一:利用queryset方法
    models.Book.objects.filter(pk=1).update(price=22)
# 方式二:利用对象 改方法不推荐使用,推荐使用queryset方法
    book_obj=models.Book.objects.get(pk=1)
    book_obj.price=22
    book_obj.save()
# 利用对象的修改 内部其实是重头到位将数据的所有字段都重新写一遍

get和filter区别

  1. filter获取到的是一个queryset对象,类似于一个列表
  2. get获取到的直接就是数据对象本身

当条件不存在的情况下:

​ filter不报错直接返回一个空,推荐使用

​ get直接报错,且不能获取多个值,所以不推荐使用get方法

删除数据

# 第一种:利用queryset方法 delete()
    models.Books.objects.filter(pk=3).delete()
# 第二种:利用对象方法
    book_obj=models.Books.objects.fliter(pk=3)
    book_obj.delete()

查看所有orm语句内部对应的sql语句

 """
    如果你想查看所有的orm语句内部对应的sql语句
    你可以直接在配置文件中配置相应的代码即可
    
 """
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

"""
    orm语句的查询默认都是惰性查询
    只有当你真正要使用数据的时候才会执行orm语句。如print时候
"""

查询数据13条

'''
1:all() 查询所有,返回的结果queryset对象
列子:
    res=models.Book.objects.all()


2:filter()  筛选 相当原生的sql语句里的where关键字,返回的结果是Queryset对象
列子:
    res = models.Books.objects.filter(pk=1,title='三')  支持多个参数 并且是and关系


3:get()  筛选 获取的是数据对象本身,条件不存在直接报错 并且查询条件必须是唯一的
列子:
     res = models.Books.objects.get(title='西游记')
     
4:first():取queryset中第一个数据对象
列子:
    res=models.Book.objects.filter(title='西游记').first()
    
5:last():取queryset中最后一个数据对象
列子:
    res = models.Books.objects.filter(title='西游记').last()
    
6:count():统计数据的个数   数字
列子:
    num = models.Books.objects.count()
    
7:values():获取数据对象中指定的字段的值,可以又多个queryset 列表套字段
列子:
    res = models.Books.objects.values('title','price')

8:values_list():获取数据对象中指定字段的值,可以又多个 列表套元组
列子:
    res = models.Books.objects.values_list('title','price')
        
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():颠倒顺序,前提是跌倒的对象必须又顺序(提前排序之后才能颠倒)
列子:
    res = models.Books.objects.all()
    res1 = models.Books.objects.all().reverse() 和res一样,因为没又事先进行排序
    res2 = models.Books.objects.all().order_by('price')
    res3 = models.Books.objects.all().order_by('price').reverse()
    
11:exclude():排除什么什么之外 queryset对象
列子:
    models.Books.objects.all().exclude(title='三国演义')
    
12:exists():判断查询结果是否有值,返回结果是一个布尔值
列子:
    res = models.Books.objects.filter(pk=1).exists()
    
13:distnct():对查询结果进行去重操作,去重的前提:数据必须是完全相同的情况下才能去重
列子:
     res = models.Books.objects.values('title','price').distinct()
注意:主键容易忽视
'''

神奇的双下划线查询(范围查找)

'''
1:__gt:大于
列子:
     res = models.Books.objects.filter(price__gt=500)

2:__lt:小于
列子:
    res = models.Books.objects.filter(price__lt=400)

3:__gte:大于等于
列子:
    res = models.Books.objects.filter(price__gte=444.66) 
    res = models.Books.objects.filter(price__gte=500)
    
4:__lte:小于等于
列子:
    res = models.Books.objects.filter(price__lte=500)
    
5:__in:在其中
列子:
    res = models.Books.objects.filter(price__in=[222,444,500])
    
6:__range:范围之间,顾头顾尾
列子:
     res = models.Books.objects.filter(price__range=(200,800))
     
7:__year:年份查找
列子
    res=models.Books.objects.filter(price__year='2019')

8:__month:月份
    res = models.Books.objects.filter(publish_date__month='1')
'''

模糊查询

MySQL中的模糊查询
        关键字 like
            模糊匹配的符号
                %:匹配任何个数的任意字符
                _:匹配一位任意的字符
'''
1:__statrswith:以...开头
列子:
    res = models.Books.objects.filter(title__startswith='三')

2:__endswith:以...结尾
列子:
    res = models.Books.objects.filter(title__startswith='三')
    
3:__contains:包含...
列子:
    res = models.Books.objects.filter(title__contains='游')      默认区分大小写
    res = models.Books.objects.filter(title__icontains='p')     忽略大小写 加i
    
'''

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

'''
增:
    第一种:直接传表里面的实际字段 跟数据主键值  publish_id
    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()  # 默认就是级联删除 级联更新
'''

多对多字段数据增删改查

'''
增:add()
    book_obj = models.Book.objects.filter(pk=2).first()
    print(book_obj.publish)     点外键字段 可能会直接获取到外键关联的数据对象
    给当前这一本书绑定作者
    麻瓜做法  自己直接去操作第三张表
    print(book_obj.authors)     已经跨到第三张表了
    book_obj.authors.add(1)     在第三张表里面给书籍绑定一个主键为1的作者
    book_obj.authors.add(1,2)   在第三张表里面给书籍绑定一个主键为1和2的作者
    
    author_obj = models.Author.objects.filter(pk=1).first()
    author_obj1 = models.Author.objects.filter(pk=2).first()
    book_obj.authors.add(author_obj)
    book_obj.authors.add(author_obj,author_obj1)
    
     add方法 能够朝第三张关系表添加数据
        即支持传数字:add(1,2)
        也支持传对象:add(author_obj,author_obj1)
        并且两者都可以是多个
        
改:set() 
    book_obj = models.Book.objects.filter(pk=2).first()
    book_obj.authors.set((1,3))
    book_obj.authors.set([1,])
    author_obj = models.Author.objects.filter(pk=1).first()
    author_obj1 = models.Author.objects.filter(pk=2).first()
    book_obj.authors.set((author_obj,author_obj1))
    
    set修改多对多关系中的数据既可以传数字也可以传对象,但是需要注意是括号内必须是
    可迭代对象,都支持多个
     set((1,3))
     set((author_obj,author_obj1))
     
     
删:remove()
    book_obj = models.Book.objects.filter(pk=2).first()
    book_obj.authors.remove(100)
    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)
    book_obj.authors.remove(author_obj,author_obj1)
    
    remove既可以传数字 也可以穿对象,并且都支持传多个 不需要迭代
            remove(1,2)
            remove(author_obj,author_obj1)
            
清空:clear()
    book_obj = models.Book.objects.filter(pk=2).first()
    book_obj.authors.clear()
    clear清空书籍相关所有记录  括号内不需要传递参数 
'''

跨表联查

'''
正反向查询:
 关系字段在谁哪 由谁查谁就是正向,如果关系字段 就是反向
        正向查询按字段
        反向查询按表名小写 + _set
        
基于对象跨表查询    子查询 分步骤操作

1.查询书籍主键为2的出版社名称
     book_obj = models.Book.objects.filter(pk=2).first()
     print(book_obj.publish)  # 出版社对象
     print(book_obj.publish.name)
     
2.查询书籍主键为4的作者姓名
     book_obj = models.Book.objects.filter(pk=4).first()
     print(book_obj.authors)  # app01.Author.None
     print(book_obj.authors.all())
     
3.查询作者是jason的手机号码
     author_obj = models.Author.objects.filter(name='jason').first()
     print(author_obj.author_detail)
     print(author_obj.author_detail.phone)
     
什么时候需要加all 
     当正向查询点击外键字段数据有多个的情况下 需要.all()
     app01.Author.None  一旦看到该结果 只需要加.all()即可
    
4.查询出版社是东方出版社出版过的书籍
     publish_obj = models.Publish.objects.filter(name='东方出版社').first()
     print(publish_obj.book_set)  # app01.Book.None
     print(publish_obj.book_set.all())

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())  # app01.Book.None

6.查询手机号是120的作者姓名
     author_detail_obj = models.AuthorDetail.objects.filter(phone=120).first()
     print(author_detail_obj.author)
     print(author_detail_obj.author.email)
 注意:_set:
      什么时候反向查询的时候表名小写需要加_set
        一对多
        多对多
    
      一对一不需要加_set
'''

基于双下滑线的跨表联查

'''
inner join
left join
right join
union

1.查询书籍pk为2的出版社名称
     正向
     res = models.Book.objects.filter(pk=2).values('publish__name')  # 写外键字段就相当于已经跨到外键字段所关联的表
     你想要改表的哪个字段信息 你只需要加__获取即可
     反向
     res = models.Publish.objects.filter(book__pk=2).values('name')
     print(res)
     
2.查询书籍pk为2的作者姓名和邮箱
     models.Book.objects.filter(pk=2).values('authors__name','authors__email')
      
     res = models.Author.objects.filter(book__pk=2).values('name','email')
     print(res)
     models后面点的谁 就以谁为基表
 

3.查询作者是egon的家庭地址
    res = models.Author.objects.filter(name='egon').values('author_detail__addr')
    print(res)
    res = models.AuthorDetail.objects.filter(author__name='egon').values('addr')
    print(res)


4.查询出版社是东方出版社出版过的书的名字
    res = models.Publish.objects.filter(name='东方出版社').values('book__title')
    print(res)
    res = models.Book.objects.filter(publish__name='东方出版社').values('title')
    print(res)

5.查询书籍pk是2的作者的手机号
   res = models.Book.objects.filter(pk=2).values('authors__author_detail__phone')
   print(res)
   res = models.Author.objects.filter(book__pk=2).values('author_detail__phone')
   print(res)
'''

猜你喜欢

转载自www.cnblogs.com/hj59988326/p/11945973.html