模型层

Posted yushan1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模型层相关的知识,希望对你有一定的参考价值。

1. ORM查询

'''
如果你想查看orm语句内部真正的sql语句有两种方式
    1.如果是queryset对象 可以直接点query查看
    2.配置文件中 直接配置
'''
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level': 'DEBUG',
        },
    }}

2. django测试环境搭建

import os

if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE","one_search.settings")
    import django
    django.setup()
    # 在下面可以测试django任何的py文件

3. 单表查询

# 增
## 1
models.Book.objects.create(title='西游记',price=66.66)
## 2
book_obj = models.Book(title='红楼梦',price=88.88)
book_obj.save()


# 改
# 把表中id为1的书价格改为369.12
models.Book.objects.filter(pk=1).update(price=369.12)

# 把表中id为1的书的名称改为python
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.title = 'python'
book_obj.save()

# 删
models.Book.objects.filter(pk=1).delete()

# 查
# 只要是queryset对象就可以无限制的点queryset对象的方法
# queryset.filter().filter().filter()

# 1.all()   查询所有   QuerySet
res = models.Book.objects.all()   # 惰性查询
print(res)     # <QuerySet [<Book: python>, <Book: 三国演义>, <Book: 红楼梦>]>
for i in res:
    print(i.title)

# 2.filter()   QuerySet
res = models.Book.objects.filter(pk=2)
print(res)     # <QuerySet [<Book: 三国演义>]>

# 3.get()   数据对象本身
res = models.Book.objects.get(pk=2)
print(res)     # 三国演义

# 4.first()   第一个
res = models.Book.objects.all().first()
print(res)     # python

# 5.last()   最后一个
res = models.Book.objects.all().last()
print(res)     # 红楼梦

# 6.exclude()   除此之外
res = models.Book.objects.exclude(pk=1)
print(res)     # <QuerySet [<Book: 三国演义>, <Book: 红楼梦>]>

# 7.values()  QuerySet   列表套字典
res = models.Book.objects.values('title')
print(res)     # <QuerySet [{'title': 'python'}, {'title': '三国演义'}, {'title': '红楼梦'}]>
for r in res:
    print(r.get('title'))
    
# 8.values_list()   QuerySet   列表套元组
res = models.Book.objects.values_list('title')
print(res)     # <QuerySet [('python',), ('三国演义',), ('红楼梦',)]>

# 9.count()   统计数据的个数
res = models.Book.objects.count()
res1 = models.Book.objects.all().count()
print(res)     # 3
print(res1)    # 3

# 10.distinct()   去重:数据必须是一模一样的情况下才能去重
res = models.Book.objects.all().distinct()
print(res)     # <QuerySet [<Book: python>, <Book: 三国演义>, <Book: 红楼梦>, <Book: python>]>
res1 = models.Book.objects.values('title','price').distinct()
# < QuerySet[{'title': 'python', 'price': Decimal('369.12')},{'title': '三国演义', 'price': Decimal('55.55')},{'title': '红楼梦', 'price': Decimal('88.88')}] >
print(res1)

# 11.order_by()   # 排序
res = models.Book.objects.order_by('price')
print(res)     # <QuerySet [<Book: 三国演义>, <Book: 红楼梦>, <Book: python>, <Book: python>]>
res1 = models.Book.objects.order_by('-price')
print(res1)    # <QuerySet [<Book: python>, <Book: python>, <Book: 红楼梦>, <Book: 三国演义>]>

# 12.reverse()   前面必须是先结果排序才可以反转
res = models.Book.objects.order_by('price').reverse()
print(res)     # <QuerySet [<Book: python>, <Book: python>, <Book: 红楼梦>, <Book: 三国演义>]>

# 13.exists()   是否存在
res = models.Book.objects.filter(pk=1).exists()
print(res)     # True


"""神奇的双下划线查询"""
# 查询价格大于200的书籍
# 查询价格大于200的书籍
res = models.Book.objects.filter(price__gt=200)
print(res)     # <QuerySet [<Book: python>]>

# 查询价格小于200的书籍
res = models.Book.objects.filter(price__lt=200)
print(res)     # <QuerySet [<Book: 三国演义>, <Book: 红楼梦>]>

# 查询价格大于或者等于200的书籍
res = models.Book.objects.filter(price__gte=200)
print(res)    # <QuerySet [<Book: python>, <Book: django>]>

# 查询价格小于或者等于200的书籍
res = models.Book.objects.filter(price__lte=200)
print(res)     # <QuerySet [<Book: 三国演义>, <Book: 红楼梦>, <Book: django>]>

# 价格是200 或者是55.55 或者88.88
res = models.Book.objects.filter(price__in=[200,55.55,88.88])
print(res)     # <QuerySet [<Book: django>]>

# 价格在200 到500之间的书籍
res = models.Book.objects.filter(price__range=(100,500))   # 顾头不顾尾
print(res)     # <QuerySet [<Book: python>, <Book: django>]>


# 模糊匹配
# mysql: like  %  _
# 查询书籍名称中包含p的
res = models.Book.objects.filter(title__contains='p')   # 区分大小写
print(res)     # <QuerySet [<Book: python>]>
res = models.Book.objects.filter(title__icontains='p')   # 忽略大小写
print(res)     # <QuerySet [<Book: python>, <Book: Python>]>
    
    
# 查询书籍名称是以三开头的书籍
res = models.Book.objects.filter(title__startswith='三')
print(res)     # <QuerySet [<Book: 三国演义>]>
# 查询书籍名称是以梦结尾的书籍
res = models.Book.objects.filter(title__endswith='梦')
print(res)     # <QuerySet [<Book: 红楼梦>]>


# 查询出版日期是2019年的书籍
res = models.Book.objects.filter(date__year=2020)
print(res)     # <QuerySet [<Book: Python>]>
# 查询出版日期是12月的书籍
res = models.Book.objects.filter(date__month=12)
print(res)     # <QuerySet [<Book: 三国演义>]>

4. 多表查询

# 一对多字段增删改查
# 增
## 1.
models.Book.objects.create(title='三国演义',price=123.23,publish_id=1)   # publish_id直接传出版社主键值
## 2.
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title='水浒传',price=99.99,publish=publish_obj)   # publish直接传出版社数据对象

# 查
book_obj = models.Book.objects.filter(pk=1).first()
print(book_obj.publish)     # Publish object   # 获取到当前所对应的出版社对象
print(book_obj.publish_id)   # 1   # 获取到的就是表中的实际字段

# 改
models.Book.objects.filter(pk=1).update(publish_id=3)
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.filter(pk=1).update(publish=publish_obj)

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


# 多对多字段的增删改查
# 增   add()
# 给主键为3的书籍添加两个作者 1 2
book_obj = models.Book.objects.filter(pk=3).first()
# print(book_obj.authors)   # 就相当于 已经在书籍和作者的关系表了
book_obj.authors.add(2)
book_obj.authors.add(1,2)   # 如果有记录就不变,没有就加
 """
add() 括号内既可以传数字也可以传数据对象,并且都支持传多个
"""

# 修改关系   set()
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.authors.set([3,])
book_obj.authors.set([3,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,))
book_obj.authors.set((author_obj,author_obj1))
"""
set() 括号内 既可以传数字也传对象 
并且也是支持传多个的
但是需要注意 括号内必须是一个可迭代对象
"""

# 删   remove()
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.authors.remove(2)
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() 括号内 既可以传数字也传对象 
并且也是支持传多个的
"""

# 清空   clear()
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.authors.clear()
"""clear()括号内不需要传任何参数 直接清空当前书籍对象所有的记录"""



"""
ORM跨表查询
    1.子查询
    2.连表查询

正反向的概念
    外键字段在谁那儿 由谁查谁就是正向
    
    谁手里有外键字段 谁就是正向查
    没有外键字段的就是反向
    
    书籍对象 查  出版社    外键字段在书籍       正向查询
    出版社 查 书籍         外键字段在书籍       反向查询

正向查询按字段
反向查询按表名小写 ...
"""
# 1.基于对象的跨表查询    子查询
# 1.查询书籍是三国演义的出版社名称
book_obj = models.Book.objects.filter(title='三国演义').first()
# 正向查询按字段
print(book_obj.publish.name)  # 南方出版社
print(book_obj.publish.addr)  # 南京

# 2.查询书籍主键是3的作者姓名
book_obj = models.Book.objects.filter(pk=3).first()
# print(book_obj.authors)     # app01.Author.None
print(book_obj.authors.all())     # <QuerySet [<Author: aa>, <Author: zz>]>

# 3.查询作者是aa的手机号
author_obj = models.Author.objects.filter(name='aa').first()
print(author_obj.author_detail.phone)     # 110
print(author_obj.author_detail.addr)     # 上海
"""
正向查询 按字段 
当该字段所对应的数据有多个的时候 需要加.all()
否者点外键字段直接就能够拿到数据对象
"""

# 反向查询按表名小写
# 4.查询出版社是东方出版社出版过的书籍
publish_obj = models.Publish.objects.filter(name='东方出版社').first()
print(publish_obj.book_set)     # app01.Book.None
print(publish_obj.book_set.all())     # <QuerySet [<Book: 红楼梦>]>

# 5.查询作者是aa写过的所有的书
author_obj = models.Author.objects.filter(name='aa').first()
print(author_obj.book_set)     # app01.Book.None
print(author_obj.book_set.all())     # <QuerySet [<Book: 三国演义>, <Book: 西游记>]>

# 6.查询手机号是110的作者
author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first()
print(author_detail_obj.author)     # aa
print(author_detail_obj.author.name)     # aa
print(author_detail_obj.author.age)     # 20
'''
反向查询按表名小写
    什么时候需要加_set
        当查询的结果可以是多个的情况下 需要加_set.all()
    什么时候不需要加_set
        当查询的结果有且只有一个的情况下 不需要加任何东西 直接表名小写即可
'''


# 2.基于双下划线的跨表查询   连表查询
"""
MySQL
    left join
    inner join
    right join
    union
"""
# 1.查询书籍是三国演义的出版社名称
# 正向
res = models.Book.objects.filter(title='三国演义').values('publish__name')
print(res)     # <QuerySet [{'publish__name': '南方出版社'}]>
# 反向
res = models.Publish.objects.filter(book__title='三国演义').values('name')
print(res)     # <QuerySet [{'name': '南方出版社'}]>

# 2.查询作者是aa的手机号码
# 正向
res = models.Author.objects.filter(name='aa').values('author_detail__phone')
print(res)     # <QuerySet [{'author_detail__phone': 110}]>
# 反向
res = models.AuthorDetail.objects.filter(author__name='aa').values('phone')
print(res)     # <QuerySet [{'phone': 110}]>

# 3.查询手机号是120的作者姓名
# 正向
res = models.AuthorDetail.objects.filter(phone=120).values('author__name')
print(res)     # <QuerySet [{'author__name': 'zz'}]>
# 反向
res = models.Author.objects.filter(author_detail__phone=120).values('name')
print(res)     # <QuerySet [{'name': 'zz'}]>

# 4.查询出版社是东方出版社出版的书籍名称
# 正向
res = models.Publish.objects.filter(name='东方出版社').values('book__title')
print(res)     # <QuerySet [{'book__title': '红楼梦'}]>
# 反向
res = models.Book.objects.filter(publish__name='东方出版社').values('title')
print(res)     # <QuerySet [{'title': '红楼梦'}]>

# 5.查询作者是aa的写过的书的名字和价格
# 正向
res = models.Author.objects.filter(name='aa').values('book__title','book__price')
print(res)   # <QuerySet [{'book__title': '三国演义', 'book__price': Decimal('123.23')}, {'book__title': '西游记', 'book__price': Decimal('88.88')}]>
# 反向
res = models.Book.objects.filter(authors__name='aa').values('title','price')
print(res)   # <QuerySet [{'title': '三国演义', 'price': Decimal('123.23')}, {'title': '西游记', 'price': Decimal('88.88')}]>

# 6.查询书籍是三国演义的作者的手机号
res = models.Book.objects.filter(title='三国演义').values('authors__author_detail__phone')
print(res)   # <QuerySet [{'authors__author_detail__phone': 110}]>

以上是关于模型层的主要内容,如果未能解决你的问题,请参考以下文章

使用片段时 Intellij 无法正确识别 Thymeleaf 模型变量

php 一个自定义的try..catch包装器代码片段,用于执行模型函数,使其成为一个单行函数调用

如何防止在背面片段导航上再次设置视图模型

微信小程序视图层WXML_模板

Cg入门19:Fragment shader - 片段级模型动态变色

Cg入门20:Fragment shader - 片段级模型动态变色(实现汽车动态换漆)