【1024 | Day52】Django基础之模型层(models.py)

Django基础之模型(models)层(上)

Django测试环境搭建:拷贝manage.py中的行代码放到tests.py文件中导入模块

import django`,`django.setup()

如果你想查看orm语句内部真正的sql语句有2种方法:

1.如果是queryset对象,就可以.query查看该queryset对象的内部sql语句

2.在settings.py文件中配置

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. 单表查询

1.1 增删改查

  • 方式一:
models.Book.objects.create(title = '三国演义',price = 12.22)
  • 方式二:
book_obj = models.Book(title='三国演义',price='12.22')
book_obj.save()

models.Book.objects.filter(pk=2).delete()

models.Book.objects.filter(pk=2).update(title = '红楼梦',price = 22.22)

res = models.Book.objects.filter(pk=2)

1.2 必知必会13条

all():查所有,查询结果为Queryset对象

res = models.Book.objects.all()
print(res)

filter:查询结果为Queryset对象

res = models.Book.objects.filter(pk=2)

get():查询结果为数据对象本身,和filter查询相似,不推荐使用

res = models.Book.objects.get(pk=2)

first():查询第一个

res = models.Book.objects.first()

last():查询最后一个

res = models.Book.objects.last()   #res可以.title,.price

exclude():哪一个排除之外

res = models.Book.objects.exclude(pk=3)

values():查询结果为列表套字典的Queryset对象

res = models.Book.objects.values('title')

value_list():查询结果为列表套元组的Queryset对象

res = models.Book.objects.values_list('title')

count():统计数据的条数

res = models.Book.objects.count('title')
res = models.Book.objects.all.count('title')

distinct():数据必须是一模一样的情况下去重

res = models.Book.objects.distinct()  #无变化
res = models.Book.objects.values('title').distinct()

order_by():排序

res = models.Book.objects.order_by('price')   #默认升序
res = models.Book.objects.order_by('-price')   #降序

reverse():排序后反转(才有意义)

res = models.Book.objects.reverse()  

exists():是否存在

models.Book.objects.filter(pk=1).exists()

1.3 双下划线查询(升级!!!)

查询价格大于200的书籍

models.Book.objects.filter(price__gt=200)

查询价格小于200的书籍

models.Book.objects.filter(price__lt=200)

查询价格大于等于200的书籍

models.Book.objects.filter(price__gte=200)

查询价格小于等于200的书籍

models.Book.objects.filter(price__lte=200)

查询价格是200元或者300元的书籍

res = models.Book.objects.filter(price__in=[200,300]) 

查询价格是200到500元之间的书籍

res = models.Book.objects.filter(price__range=(200,500))  #顾头不顾尾

查询书籍中包含p的书籍

res = models.Book.objects.filter(title__contains='p')   #区分大小写
res = models.Book.objects.filter(title__icontains='p')   #不区分大小写

查询书籍名称是以三开头的书籍

res = models.Book.objects.filter(title__startswith="三")

查询书籍名称是以三结尾的书籍

res = models.Book.objects.filter(title__endswith="三")

查询出版日期是2019年的书籍

res = models.Book.objects.filter(data__year="2019")

查询出版日期是10月份的书籍

res = models.Book.objects.filter(data__month="10")

2. 多表查询

2.1 外键的字段的增删改查

2.1.1 一对多字段的增删改查

  • 方式一:
models.Book.objects.create(title='xxx',price=66.66,publish_id=1)
  • 方式二:
publish_obj =models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title='xxx',price=66.66, publish_id=publish_obj)

book_obj = models.Book.objects.filter(pk=1).first()
print(book_obj.publish.name)
print(book_obj.publish_id)

  • 方式一:
models.Book.objects.filter(pk=3).update(publish_id=3)
  • 方式二:
publish_obj = models.Publish.objects.filter(pk=1).first()
models.Book.objects.filter(pk=3).update(publish_id=publish_obj)  #给书更换出版社

models.Book.objects.filter(pk=3).delete()

2.1.2 多对多字段的增删改查

  • 方式一:
book_obj = models.Book.objects.filter(pk=3).first()
print(book_obj.author)  # 就相当于已经到书籍与作者的关系表中
book_obj.author.add(1)
book_obj.author.add(2, 3)  # 还可以添加多个值

author_obj = models.Author.objects.filter(pk=1).first()
book_obj.author.add(author_obj)

author_obj = models.Author.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=2).first()
book_obj.author.add(author_obj, author_obj1)   # 还可以添加多个值

'''
add()  括号内 既可以串数字,也可以传对象
并且支持传多个
但是括号内必须是可迭代对象
'''

#方式一
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.author.remove(2)
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, author_obj1))

'''
remove()  括号内 既可以串数字,也可以传对象
并且支持传多个
'''
#清空

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

'''clear括号内不需要传任何参数 直接清空当前书籍对象所有的记录'''

#方式一
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.author.set([3, ])


#方式二
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()  括号内 既可以串数字,也可以传对象
并且支持传多个
但是括号内必须是可迭代对象
'''

2.2 表与表之间的关联查询

2.2.1 基于对象的跨表查询(子查询)

  • 正向查询按字段
  • 反向查询按表名小写

当该字段所对应的数据有多个的时候 需要加.all( ),否则点外键字段直接就能够拿到数据对象

查询书籍是Python入门的出版社名称(一对多)

book_obj = models.Book.objects.filter(title='python入门').first()
print(book_obj.publish.name)
print(book_obj.publish.addr)

查询书籍主键为6的作者姓名(多对多)

book_obj = models.Book.objects.filter(pk=6).first()
print(book_obj.author)  #None
print(book_obj.author.all())   #拿到当前这本书所有的作者

查询作者是Jason的手机号(一对一)

author_obj = models.Author.objects.filter(name='jason').first()
print(author_obj.author_detail.phone)

查询出版社是东方出版社出版过的书籍

publish_obj = models.Publish.objects.filter(name="东方出版社").first()
print(publish_obj.book_set.all())

查询作者是Jason写过的所有的书

author_obj = models.Author.objects.filter(name='json').first()
print(author_obj.book_set.all())

查询手机号是110的作者

phone_obj = models.AuthorDetail.objects.filter(phone=110).first()
print(phone_obj.author)

2.2.2 基于双下划线的跨表查询(连表查询)

查询书籍是Python入门的出版社名称

正向:

models.Book.objects.filter(name='python入门').values('publish__name')

反向:

models.Publish.objects.filter(book__title='python入门').value('name')

查询作者是jason的手机号码

正向:

models.Author.objects.filter(name='json').values('author_detail__phone')

反向

models.AuthorDetail.objects.filter(author__book__author='json').values('phone','author_age')  #还可以加自己的年龄

查询手机号是120的作者姓名和地址

正向

models.AuthorDetail.objects.filter(phone='120').values('author__name')

反向

models.Author.objects.filter(author_detail__phone=120).values('name',,'author_detail__addr')

查询出版社是东方出版社出版的书籍名称

正向:

models.Publish.objects.filter(name='东方出版社').values('book__title')

反向:

models.Book.objects.filter(author__book__publish='东方出版社').values('title')

查询作者是jason的写过的书的名字和价格

正向:

models.Author.objects.filter(name='json').values('book__title','book__price')

反向:

models.Book.objects.filter(author__name='json').values('title','price')

查询书籍是python入门的作者的手机号

正向:

models.Book.objects.filter(name='python入门').values('authors__author_detail__phone')

反向:

models.AuthorDetail.objects.filter(author__book__title='python入门').values('phone')

3. 拓展

auto_now:每次修改数据的时候,都会自动更新时间

auto_now_add:在创建数据的时候,会自动将当前时间记录下来,后期如果你不人为修改的话,数据不变

queryset:只要是queryset对象就可以无限的点queryset对象的方法

eg:一步步筛选

queryset.excult(pk=1).filter(pk=3).filter(pk=4)

return:return返回的必须是字符串,其他的类型直接报错,此处可以写在models.py中。

正反向概念:

书籍对象查出版社 外键字段在书籍 正向查询

出版社查书籍 外键字段在书籍 反向查询

注意:计算机语言是基于英语语境开发的语言,所以可以用英语的语法角度出发理解,不必太中式思考。无论是正向还是反向查询,只需要按着你想查找的结果为最终目的去运用命令,可以轻松理解查询这一块的知识。

posted @ 2019-10-24 19:01  fxyadela  阅读(358)  评论(0编辑  收藏  举报