Django学习——Django测试环境搭建、单表查询关键字、神奇的双下划线查询(范围查询)、图书管理系统表设计、外键字段操作、跨表查询理论、基于对象的跨表查询、基于双下划线的跨表查询

Django测试环境搭建

ps:
    1.pycharm连接数据库都需要提前下载对应的驱动
    2.自带的sqlite3对日期格式数据不敏感
    	如果后续业务需要使用日期辅助筛选数据那么不推荐使用sqlite3
        
方式1: 任意创建一个py文件,在该文件内书写固定的配置
import os
if __name__ == '__main__':
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoProject2.settings')
    import django
    django.setup()
    # 单独测试Django py文件
    
方式2: 直接使用pycharm提供的python console

单表查询关键字

QuerySet对象方法
	query  # 查看orm内部对应的SQL语句
    
 	 from app01 import models
    # res = models.Books.objects.all()
    # print(res)  # <QuerySet []>
    
    # 增
    # res = models.Books.objects.create(title='三国演义',price=234.43)
    # res = models.Books.objects.create(title='水浒传',price=456.22)
    # res = models.Books.objects.create(title='西游记',price=687.90)
    # print(res.title)
    '''create返回值就是当前被创建的数据对象'''
    # 查
    # res = models.Books.objects.all()
    # print(res.query)
    # SELECT `app01_books`.`id`, `app01_books`.`title`, `app01_books`.`price`, `app01_books`.`publish_time` FROM `app01_books`
    # res = models.Books.objects.filter()  # QuerySet
    # print(res.query)
    # res = models.Books.objects.filter(title='西游记',price=123.23)  # AND
    # res = models.Books.objects.filter(title='jason')
    # res = models.Books.objects.filter(title='西游记')
    # res = models.Books.objects.filter(title='西游记')[0]
    # print(res)  # <QuerySet [<Books: 西游记>]>
    """filter括号内可以放多个参数 默认是and关系 返回一个QuerySet对象 条件不符合不会报错返回QuerySet空对象 可以通过索引提取对象本身"""
    # res1 = models.Books.objects.get(title='西游记')
    # print(res1)  # 西游记
    """get括号内可以放多个参数 默认是and关系 直接拿到对象本身 条件不符合直接报错 不推荐使用"""
    # 改
    # res = models.Books.objects.filter(pk=1).update(price=666.66)
    # print(res)  # 返回值是受影响的行数

    # book_obj = models.Books.objects.filter(pk=2).first()
    # book_obj.price = 999.66
    # book_obj.save()  # 效率低(所有字段重新写一遍)
    """pk能够自动查找到当前表的主键字段 我们不需要查看当前表主键字段名"""
    # 删
    # models.Books.objects.filter(pk=1).delete()
    
    # 1.first()  取第一个数据对象
    # res = models.Books.objects.all().first()
    # res1 = models.Books.objects.all()[0]
    # res2 = models.Books.objects.all()[0:2]
    # print(res,res1,res2)
    """QuerySet对象还支持切片操作 但是只能填正数"""
    # 2.last()  取最后一个数据对象
    # res = models.Books.objects.all().last()
    # print(res)
    # 3.values()  获取数据指定字段的值
    # res = models.Books.objects.all().values('title','publish_time')
    # res = models.Books.objects.values('title','publish_time')
    # print(res.query)
    """all()加不加都表示所有数据 values获取的结果 类似于列表套字典"""
    # 4.values_list()  获取数据指定字段的值
    # res = models.Books.objects.values_list('title','publish_time')
    # print(res)
    """values_list获取的结果 类似于列表套元组"""
    # 5.order_by()  排序
    # res = models.Books.objects.order_by('price')  # 默认是升序
    # print(res)
    # res1 = models.Books.objects.order_by('-price')  # 减号降序
    # print(res1)
    # 6.count()  计数
    # res = models.Books.objects.count()  # 统计数据条数
    # print(res)
    # 7.distinct()  去重
    # res = models.Books.objects.distinct()
    # print(res)
    # res = models.Books.objects.values('title').distinct()
    # print(res)
    """去重的前提是数据必须是一模一样  一定不能忽略主键"""
    # 8.exclude()  排除什么什么在外  取反操作
    # res = models.Books.objects.exclude(title='西游记')
    # print(res.query)
    # 9.reverse()
    # res = models.Books.objects.all()
    # res1 = models.Books.objects.reverse()
    # res2 = models.Books.objects.order_by('price').reverse()
    # print(res)
    # print(res1)
    # print(res2)
    """reverse需要先排序之后才能反转"""
    # 10.exists()  判断是否有数据  返回布尔值
    # res = models.Books.objects.all().exists()
    # print(res)

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

    # 1.查询价格大于700的书籍
    # res = models.Books.objects.filter(price__gt=700)  # WHERE `app01_books`.`price` > 700
    # print(res)
    # print(res.query)
    # 2.查询价格小于700的书籍
    # res = models.Books.objects.filter(price__lt=700)
    # print(res)
    # 查询价格大于等于700 小于等于700
    # res1 = models.Books.objects.filter(price__gte=700)  # WHERE `app01_books`.`price` >= 700
    # res2 = models.Books.objects.filter(price__lte=700)  # WHERE `app01_books`.`price` <= 700
    # print(res1.query,res2.query)
    # 3.查询价格要么是666.66 要么是999.66 要么是10000
    # res = models.Books.objects.filter(price__in=[666.66,999.66,10000])
    # print(res)
    """python对数字不是很敏感 精确度不高 很多时候我们会采取字符串存储数字类型"""
    # 4.查询价格在500到800之间的
    # res = models.Books.objects.filter(price__range=(500,800))  # WHERE `app01_books`.`price` BETWEEN 500 AND 800
    # print(res.query)

    # 5.查询书名中包含字母s的书
    # res = models.Books.objects.filter(title__contains='s')  # 区分大小写
    # print(res.query)  #  WHERE `app01_books`.`title` LIKE BINARY %s%
    # 忽略大小写
    # res = models.Books.objects.filter(title__icontains='s')
    # print(res.query)  # WHERE `app01_books`.`title` LIKE %s%

    # 查询以什么开头 结尾
    # res = models.Books.objects.filter(title__startswith='三')
    # print(res)

    # 6.查询出版日期是2021的书
    # res = models.Books.objects.filter(publish_time__year=2021)
    # print(res.query)  # WHERE `app01_books`.`publish_time` BETWEEN 2021-01-01 AND 2021-12-31
    # 7.查询出版日期是9月的书
    # res = models.Books.objects.filter(publish_time__month=9)
    # print(res)
    # 8.查询出版日期是20日的书
    # res = models.Books.objects.filter(publish_time__day=20)
    # print(res)

图书管理系统表设计

class Book(models.Model):
    title = models.CharField(verbose_name='书名', max_length=32)
    price = models.DecimalField(verbose_name='价格', max_digits=8, decimal_places=2)
    publish_time = models.DateField(verbose_name='出版日期',auto_now_add=True)
    # 一对多 外键字段建在多的一方
    # 出版社外键 一对多
    publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)  # 默认就是主键
    """自动在外键字段后面加_id后缀"""
    # 多对多 外键字段推荐建在查询频率较高的表中
    # 作者外键 多对多
    authors = models.ManyToManyField(to='Author')  # 自动帮你创建书籍和作者的第三张表
    """虚拟字段不会在表中实例化出来 而是告诉ORM创建第三张关系表"""


class Publish(models.Model):
    title = models.CharField(verbose_name='名称',max_length=32)
    addr = models.CharField(verbose_name='地址',max_length=128)
    email = models.EmailField(verbose_name='邮箱')


class Author(models.Model):
    name = models.CharField(verbose_name='姓名',max_length=32)
    age = models.IntegerField(verbose_name='年龄')
    # 一对一 外键字段推荐建在查询频率较高的表中
    # 作者详情外键 一对一
    author_detail = models.OneToOneField(to='AuthorDetail',on_delete=models.CASCADE)
    """自动在外键字段后面加_id后缀"""


class AuthorDetail(models.Model):
    phone = models.BigIntegerField(verbose_name='电话')
    addr = models.CharField(verbose_name='地址',max_length=32)

"""
作者详情表
作者表
出版社表

书籍表和关系表通过orm实现
"""

外键字段操作

   # 外键字段
    # 直接传主键值
    # models.Book.objects.create(title='聊斋',price=666.98,publish_id=1)
    # models.Book.objects.create(title='聊斋志异2',price=666.98,publish_id=2)
    # 传数据对象
    # publish_obj = models.Publish.objects.filter(pk=1).first()
    # models.Book.objects.create(title='神雕侠侣',price=234.56,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=4).update(publish=publish_obj)

    # 多对多外键字段
    # 增
    book_obj = models.Book.objects.filter(pk=1).first()
    # 主键值
    # book_obj.authors.add(2)  # 去第三张关系表中 与作者主键为2的绑定关系
    # 作者对象
    # author_obj = models.Author.objects.filter(pk=3).first()
    # book_obj.authors.add(author_obj)
    # 括号内支持传多个参数
    # book_obj.authors.add(1,2)
    # author_obj1 = models.Author.objects.filter(pk=1).first()
    # author_obj2 = models.Author.objects.filter(pk=2).first()
    # book_obj.authors.add(author_obj1,author_obj2)

    # 改
    # book_obj.authors.set([3,])
    # book_obj.authors.set((1,2))
    # author_obj1 = models.Author.objects.filter(pk=1).first()
    # author_obj2 = models.Author.objects.filter(pk=2).first()
    # book_obj.authors.set((author_obj1,author_obj2))

    # 删
    # book_obj.authors.remove(1)
    # book_obj.authors.remove(1,2)
    # book_obj.authors.remove(author_obj1,author_obj2)

    # 清空
    # book_obj.authors.clear()  # 去第三张关系表中删除所有该书籍对应的记录
    """
    add()
    remove()
        括号内既可以传数字也可以传对象 逗号隔开即可
    set()
        括号内必须传递可迭代对象  可迭代对象内既可以传数字也可以传对象 支持多个
    clear()
        清空操作 无需传值
    """

跨表查询理论

正向
	外键字段在谁哪儿,谁查另外的就是正向
反向
	没有外键字段
# 判断是否有关联的外键字段

"""
正向查询按外键字段
反向查询按表名小写  _set
"""

基于对象的跨表查询

# 子查询
"""
1.先查询出一个对象
2.基于对象点正反向字段
"""

反向查询表名小写加_set
	查询的对象可能有多个的情况
	查询的对象只有一个的情况不需要加_set
    
# 基于对象的跨表查询
    # 1.查询聊斋书籍对应的出版社名称
    # book_obj = models.Book.objects.filter(title='聊斋').first()
    # res = book_obj.publish
    # print(res)
    # print(res.title)

    # 2.查询神雕侠侣对应的作者
    # book_obj = models.Book.objects.filter(title='神雕侠侣').first()
    # res = book_obj.authors  # app01.Author.None
    # res = book_obj.authors.all()
    # print(res)

    # 3.查询jason的地址
    # author_obj = models.Author.objects.filter(name='jason').first()
    # res = author_obj.author_detail
    # print(res)
    # print(res.phone,res.addr)

    # 4.查询东方出版社出版过的书籍
    # publish_obj = models.Publish.objects.filter(title='东方出版社').first()
    # res = publish_obj.book_set.all()
    # print(res)

    # 5.查询jason写过的书
    # author_obj = models.Author.objects.filter(name='jason').first()
    # res = author_obj.book_set.all()
    # print(res)

    # 6.查询电话是110的作者姓名
    # authordetail_obj = models.AuthorDetail.objects.filter(phone=110).first()
    # res = authordetail_obj.author
    # print(res)
    # print(res.name,res.age)

基于双下划线的跨表查询

# 链表查询
 # 基于双下划线的跨表查询
    # 1.查询聊斋书籍对应的出版社名称
    # res = models.Book.objects.filter(title='聊斋').values('publish__title')
    # print(res)
    # 2.查询神雕侠侣对应的作者
    # res = models.Book.objects.filter(title='神雕侠侣').values('authors__name','authors__age')
    # print(res)
    # 3.查询jason的地址
    # res = models.Author.objects.filter(name='jason').values('author_detail__addr')
    # print(res)
    # 4.查询东方出版社出版过的书籍
    # res = models.Publish.objects.filter(title='东方出版社').values('book__title')
    # print(res)
    # 5.查询jason写过的书
    # res = models.Author.objects.filter(name='jason').values('book__title')
    # print(res)
    # 6.查询电话是110的作者姓名
    # res = models.AuthorDetail.objects.filter(phone=110).values('author__name')
    # print(res)

    # 1.查询聊斋书籍对应的出版社名称 不能用models.Book
    # res = models.Publish.objects.filter(book__title='聊斋')
    # res = models.Publish.objects.filter(book__title='聊斋').values('title')
    # print(res)
    # 2.查询神雕侠侣对应的作者
    # res = models.Author.objects.filter(book__title='神雕侠侣').values('name')
    # print(res)
    # 3.查询jason的地址
    # res = models.AuthorDetail.objects.filter(author__name='jason').values('addr')
    # print(res)

    # 查询神雕侠侣对应的作者的电话和地址
    # res = models.Book.objects.filter(title='神雕侠侣').values('authors').values('authors__author_detail__phone','authors__author_detail__addr')
    # res = models.Book.objects.filter(title='神雕侠侣').values('authors__author_detail__phone','authors__author_detail__addr')
    # res = models.Author.objects.filter(book__title='神雕侠侣').values('author_detail__phone','author_detail__addr')
    # print(res)
    
    
1.普通函数以__开头
	说明当前函数只在当前模块(py)下使用,尽量不在外部调用
posted @ 2022-05-03 22:46  寻月隐君  阅读(26)  评论(0编辑  收藏  举报