day53 django 模型层

模型层

ORM查询

​ 如何配置测试脚本
​ 第一种:
​ 直接在某一个应用下的tests文件中书写下面内容,然后自己写两行

#当你想单独测试django中某个py文件,需要手动配置测试监本
import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")
    import django
    django.setup()
    #一定要等待测试脚本搭建完毕之后,才能导入django文件进行测试
    from app01 import models

第二种
直接新建一个任意名称的py文件,在里面写上配置

#当你想单独测试django中某个py文件,需要手动配置测试监本
import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")
    import django
    django.setup()
    #一定要等待测试脚本搭建完毕之后,才能导入django文件进行测试
    from app01 import models

如果想查看QuerySet里的SQL语句,在settings里面加上

 """
    如果你想查看所有的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',
        },
    }
}

1.单表操作

创建一张表

class Books(models.Model):
    title=models.CharField(max_length=32)
   price=models.DecimalField(max_digits=8,decimal_places=2)
    publish_data=models.DateField()

创建数据

​ 1.create方法

    book_obj=models.Books.objects.create(title='西游记',price=123.23,publish_data='2019-12-12')
    print(book_obj)
    from datetime import date
    ctime=date.today()
    book_obj=models.Books.objects.create(title='红楼梦',price=888,publish_data=ctime)

2.利用对象的绑定方法

book_obj=models.Books(title='水浒传',price=56.33,publish_data='2000-1-21')
    book_obj.save()

修改数据

res=models.Books.objects.filter(pk=2)
    print(res)
    print(res.query) # SELECT `app01_books`.`id`, `app01_books`.`title`, `app01_books`.`price`, `app01_books`.`publish_data` FROM `app01_books` WHERE `app01_books`.`id` = 2
    '''
    pk会自动帮你查找到当前表的主键字段,后期会用pk来指代主键字段
    filter查询出来的结果是QuerySet对象
        1.只要是QuerySet对象就可以无限制的调用QuerySet的方法
            例如:fileter  create  delete 
            res=models.Books.objects.filter(pk=2).filter().filter()
        2.只要是QuerySet对象就可以点query查看当前结果内部对应的sql语句'''
    #方式1:利用QuerySet方法
    models.Books.objects.filter(pk=2).update(price=333)
    #方式2:利用对象
    book_obj=models.Books.objects.get(pk=2)#该方法不推荐使用,推荐使用queryset方法
    book_obj.price=2222
    book_obj.save()
    #利用对象的修改,内部其实是重头到尾将数据的所有字段都重写了一遍
    '''
    get和filter区别
    1.filter获取的是一个QuerySet对象,类似于一个列表
    2.get获取的是数据对象本身
    当条件不存在的情况下:
        filter不报错,直接返回一个空,推荐使用filter
        get会直接报错,所有不推荐使用'''

删除数据

    #1.利用QuerySet方法  delete()
    models.Books.objects.filter(pk=3).delete()
    #2.对象方法
    book_obj=models.Books.objects.get(pk=2)
    book_obj.delete()

查数据 必知必会13条

1.all() 查询所有 返回queryset对象
    res=models.Books.objects.all()
    print(res)
     '''
    orm语句的查询默认都是惰性查询
    只有真正使用数据的时候才会执行orm语句''
2.filter() 筛选 返回的是queryset对象
    # 相当于你原生SQL语句里面的where关键字
    res=models.Books.objects.filter(pk=5)#支持多个参数,并且是and关系
    print(res)

##### 3.get() 筛选 获取的数据对象本身

    # 条件不存在直接报错 并且查询条件必须是唯一的
    res=models.Books.objects.get(pk=4)
    print(res)
4.first() 取queryset中第一个数据对象
    res=models.Books.objects.filter(pk=4).first()
    print(res)

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

    res=models.Books.objects.filter(title='西游记').last()
    print(res)
6.count()统计数据的个数 返回数字
    num=models.Books.objects.count()
    print(num)
7.values() 获取数据对象中指定的字段的值 queryset 列表套字典
   #可以拿多个                                         res=models.Books.objects.values('title','price')
print(res)
8.values_list() 获取数据对象中指定的字段的值 queryset 列表套元组
    #  可以拿多个
res=models.Books.objects.values_list('title','price') res=models.Books.objects.filter(pk=5).values_list('title','price')
print(res)
9.order_by() 指定字段排序 返回queryset
    res=models.Books.objects.order_by('price')#默认是升序
    res=models.Books.objects.all().order_by('price') #等价 语义更明确
    res = models.Books.objects.order_by('-price')#加负号 降序
    print(res)
10.reverse() 颠倒顺序 返回queryset
    # 前提是颠倒的对象必须有顺序(提前排序之后才能颠倒)
    res = models.Books.objects.all().order_by('price')
    res=res.reverse()
    print(res)
11.exclude() 排除什么什么之外 返回queryset
    res=models.Books.objects.all().exclude(title='西游记')
    print(res)
12.exists() 判断查询结果是否有值 返回结果是一个布尔值
    res=models.Books.objects.filter(pk=5).exists()
    print(res)
    # 该方法其实不需要使用,因为数据本身自带布尔值
13.distinct() 查询结果进行去重操作 返回queryset
    # 前提:数据必须是要完全相同的情况下 才能去重(容易忽略主键)
  res=models.Books.objects.values_list('title','price').distinct()
    print(res)

2.神奇的双下划线查询

    #查询价格大于500的书籍
    res=models.Books.objects.filter(price__gt=500)
    
    #查询价格小于500的书籍
    res=models.Books.objects.filter(price__lt=500)
    
    #查询价格大于等于500的书籍
    res=models.Books.objects.filter(price__gte=500)
    
    #查询价格小于等于500的书籍
    res=models.Books.objects.filter(price__lte=500)
    
    #查询价格是222或者444或者500的书籍
    res=models.Books.objects.filter(price__in=[222,444,500])
    
    #查询价格在200到800之间的书籍
    res=models.Books.objects.filter(price__range=(200,800))
    
    #查询出版日期是2019年的书籍
  res=models.Books.objects.filter(publish_data__year='2019')

    #查询出版日期是1月份的书籍
   res=models.Books.objects.filter(publish_data__month='1')

    # 模糊查询
    '''
    mysql中的模糊查询
        关键字 like
            模糊匹配的符号
                %:匹配任何个数的任意字符
                _:匹配以为任意字符'''
    #查看书籍是以西开头的书
    res=models.Books.objects.filter(title__startswith='西')
    
    #查询书籍是以记结尾的书
    res=models.Books.objects.filter(title__endswith='记')
    
    #查询书籍名称中包含游字的书籍
    res=models.Books.objects.filter(title__contains='游')
    
    #查询书籍名称包含字母p的书籍
    res=models.Books.objects.filter(title__contains='p')#默认区分大小写
    res=models.Books.objects.filter(title__icontains='p')#忽略区分大小写

3.图书管理系统表设计

class Book(models.Model):
    title=models.CharField(max_length=32)
    price=models.DecimalField(max_digits=8,decimal_places=2)
    publish_data=models.DateField(auto_now_add=True)
    '''
    auto_now:每次修改数据的时候,都会更新修改数据时间(展示最新的依次修改时间)
    auto_now_add:当数据创建出来的时候,会自动将创建时间记录下来
    '''
    publish=models.ForeignKey(to='Pbulish')
    author=models.ManyToManyField(to='Author')

class Pbulish(models.Model):
    name=models.CharField(max_length=32)
    addr=models.CharField(max_length=64)
    def __str__(self):
        return self.name

class Author(models.Model):
    name=models.CharField(max_length=64)
    email=models.EmailField()#对应到数据库中仅仅是varchar(254),没有任何限制条件,该字段只要是字符串就行
    #仅仅是为了表达语义,如何限制:后期需要借助于校验性组件
    author_detail=models.OneToOneField(to='AuthorDetail')
    def __str__(self):
        return self.name

class AuthorDetail(models.Model):
    phone=models.BigIntegerField()
    addr=models.CharField(max_length=64)
    def __str__(self):
        return self.addr

4.外键字段(一对多)的增删改查

    #第一种
    models.Book.objects.create(title='西游记',price=233,publish_id=1)
    # 直接传表里面的实际字段,跟数据主键值 publish_id
    
    #第二种
    publish_obj=models.Pbulish.objects.filter(pk=2).first()
    models.Book.objects.create(title='红楼梦',price=555,publish=publish_obj)
    # 传虚拟字段 跟数据对象即可
    #第一种
    models.Book.objects.filter(pk=1).update(publish_id=2)
    #第二种
    publish_obj=models.Pbulish.objects.filter(pk=1).first()
  models.Book.objects.filter(pk=1).update(publish=publish_obj)
删除
    #默认就是级联产出,级联更新
    models.Pbulish.objects.filter(pk=1).delete()

5.外键字段(多对多)的增删改查

    book_obj=models.Book.objects.filter(pk=3).first()
    print(book_obj.publish)#点外键字段,可能会直接获取到外键关联的数据对象
    #给当前这本书绑定作者
    print(book_obj.author)#已经跨到第三张表
    book_obj.author.add(2)#在第三种表里面给书籍绑定一个主键为2的作者

    author_obj=models.Author.objects.filter(pk=1).first()
    author_obj1=models.Author.objects.filter(pk=2).first()
    book_obj.author.add(author_obj)
    book_obj.author.add(author_obj,author_obj1)
    '''
    add方法 能够朝第三张关系表添加数据
    既支持传数字:add(1,2)
    也支持传对象:add(author_obj,author_obj1)
    并且两者都可以传多个'''
    book_obj=models.Book.objects.filter(pk=3).first()
    book_obj.author.set((1,3))
    book_obj.author.set([1,])

    author_obj=models.Author.objects.filter(pk=1).first()
    author_obj1=models.Author.objects.filter(pk=2).first()
    book_obj.author.set((author_obj,author_obj1))
    '''
    set修改多对多关系表中的数据
    既可以传数字也可以传对象
    但是需要注意的是括号内必须是可迭代对象
    都支持多个
        set((1,3))
        set((author_obj,author_obj1))'''
    book_obj=models.Book.objects.filter(pk=3).first()
    book_obj.author.remove(1,2)

    author_obj = models.Author.objects.filter(pk=1).first()
    author_obj1=models.Author.objects.filter(pk=2).first()
    book_obj.author.remove(author_obj)
    book_obj.author.remove(author_obj,author_obj1)
    '''
    remove既可以传数字,也可以传对象
    并且都支持多个,不需要迭代
    remove(1,2)
    remove(author_obj,author_obj1)'''
清空 删除某个数据在第三张表中的所有记录
    book_obj=models.Book.objects.filter(pk=4).first()
    book_obj.author.clear()
    '''
    clear清空书籍相关所有记录,括号内不需要传递参数'''

6.跨表查询、

正反向查询:
关系字段在谁那,由谁查,谁就是正向
如果关系字段不在,就是反向
正向查询按字段,反向查询按表名小写+_set

基于对象的跨表查询 子查询 分布操作
    # 1.查询书籍主键为3的出版社名称
    book_obj=models.Book.objects.filter(pk=3).first()
    print(book_obj.publish)
    print(book_obj.publish.name)
    #2.查询书籍主键为3的作者姓名
    book_obj=models.Book.objects.filter(pk=3).first()
    print(book_obj.author)
    print(book_obj.author.all())
    # print(book_obj.author.all().first().name)
    #3.查询作者是Jason的手机号码
    author_obj=models.Author.objects.filter(name='json').first()
    print(author_obj.author_detail)
    print(author_obj.author_detail.phone)
    '''
    什么时候需要加all:
        当正向查询点击外键字段数据有多个的情况下 需要,all()
        app01.Author.None  一旦看到该结果 只需要加.all()即可'''
    #4查询出版社是东方出版社出版过的书籍
    publish_obj=models.Pbulish.objects.filter(name='西方出版社').first()
    print(publish_obj.book_set)
    print(publish_obj.book_set.all())
    #5.查询作者是Jason写过的书籍
    author_obj=models.Author.objects.filter(name='json').first()
    print(author_obj.book_set)
    print(author_obj.book_set.all())
    #6.查询手机号是1210的作者姓名
    author_detail_obj=models.AuthorDetail.objects.filter(phone=110110).first()
    print(author_detail_obj.author)
    '''
    什么时候反向查询表名小写需要加_set
    一对多  多对多
    一对一不需要加_set'''
基于双下划线的跨表查询 联表操作

    #1.查询书籍pk为3的出版社名称
    #正向:
    res=models.Book.objects.filter(pk=3).values('publish__name')
    #写外键字段就相当于已经跨到外键字段所关联的表
    #想要改表里的那个字段信息,只需加__获取即可
    #models后面点谁,谁就是基表
    print(res)
    res=models.Pbulish.objects.filter(book__pk=3).values('name')
    print(res)

    #2.查询书籍pk为3的作者姓名和邮箱
    #正向
    res=models.Book.objects.filter(pk=3).values('author__name','author__email')
    print(res)
    #反向
    res=models.Author.objects.filter(book__pk=3).values('name','email')
    print(res)

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

    #4.查询出版社是西方出版社初设过得书的名字
    #反向
    res=models.Pbulish.objects.filter(name='西方出版社').values('book__title')
    print(res)
    #正向
    res=models.Book.objects.filter(publish__name='西方出版社').values('title')
    print(res)

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

猜你喜欢

转载自www.cnblogs.com/zqfzqf/p/11946278.html