import os
    import time

    if name == “main“:
    os.environ.setdefault(“DJANGO_SETTINGS_MODULE”, “day64.settings”)
    import django

    1. django.setup()<br /> from app01 import models<br />  上面的代码是在本地进行orm测试需要添加的
    2. # 单表操作<br /> # 增<br /> # res = models.User.objects.create(name='alex', age=18, register_time='2022-5-17')<br /> # res = models.User.objects.create(name='jason', age=25, register_time='2021-5-17')
    3. # 删除, 方式1<br /> # models.User.objects.filter(pk=1).delete()<br /> # 方式二:<br /> # user_obj = models.User.objects.filter(pk=2).first()<br /> # user_obj.delete()
    4. # 修改 方式一<br /> # models.User.objects.filter(pk=3).update(name='haojiangzhu')<br /> # 方式二<br /> # user_obj = models.User.objects.filter(pk=3).first()<br /> # print(user_obj)<br /> # user_obj.age = 99<br /> # user_obj.save()
    5. # 查<br /> # filter返回的queryset对象, 数据不存在不会报错而是返回None<br /> # get方法返回分时当前数据对象, 数据不存在该方法会直接报错,不建议使用
    6. """<br /> 必知必会十三条<br /> filter() # 带有过滤条件的查询<br /> get() # 直接拿数据对象, 但是条件不存在直接报错<br /> all() # 查询所有数据<br /> first() # 拿queryset里面的第一个对象<br /> last() # 拿queryset里面的最后个对象<br /> values() # 可以获取指定的数据字段 列表套字典<br /> values_list() # 可以回去指定的数据字段 列表套元组<br /> distinct() # 去重, 去重一定是要一模一样的数据, 查询的数据带有主键, 主键都不一样, 就不能去重<br /> order_by() # 排序<br /> reverse() # 结果顺序反转(前提是数据已经排好队)<br /> count() # 计数<br /> exclude() # 排除在外<br /> exists() # 返回的是布尔值,存在True不存在False<br /> """<br /> # all<br /> # res = models.User.objects.all()<br /> # print(res)
    7. # get<br /> # res = models.User.objects.get(name='alex') # User object<br /> # print(res)
    8. # filter<br /> # res = models.User.objects.filter(name='alex') # <QuerySet [<User: User object>]><br /> # print(res)
    9. # first<br /> # res = models.User.objects.all().first() # User object<br /> # print(res)
    10. # last<br /> # res = models.User.objects.all().last()
    11. # values<br /> # res = models.User.objects.all().values('name', 'age') # <QuerySet [{'name': 'haojiangzhu', 'age': 99}><br /> # print(res)
    12. # values_list # <QuerySet [('haojiangzhu', 99), ('alex', 12), ('egon', 13)]><br /> # res = models.User.objects.all().values_list('name', 'age')<br /> # print(res)
    13. # order_by(默认正序, 加-号为倒序)<br /> # res = models.User.objects.values('name', 'age').order_by('age')<br /> # print(res)
    14. # distinct<br /> # res = models.User.objects.values('name', 'age').distinct()<br /> # print(res)
    15. # reverse()<br /> # res = models.User.objects.values('name', 'age').order_by('age')<br /> # print(res.reverse())
    16. # count()<br /> # res = models.User.objects.count()<br /> # print(res)
    17. # exclude()<br /> # res = models.User.objects.all().values('name', 'age').exclude(name='haojiangzhu')<br /> # print(res)
    18. # exists()<br /> # exists = models.User.objects.filter(name='haojiangzhu').exists()<br /> # if exists:<br /> # print('优质')
    19. # 双下划线查询<br /> # 大于, 年龄大于35岁的数据 gt<br /> # res = models.User.objects.filter(age__gt=35).values('name', 'age')<br /> # print(res)
    20. # 小于, 年龄小于35岁的数据lt<br /> # res = models.User.objects.filter(age__lt=35).values('name', 'age')<br /> # print(res)
    21. # 大于等于 gte 小于等于 lte
    22. # 或, 年龄是18 或 32 或40 in<br /> # res = models.User.objects.filter(age__in=[18, 32, 40]).values('name', 'age')<br /> # print(res)
    23. # 年龄在18-40 range<br /> # res = models.User.objects.filter(age__range=[18, 40])<br /> # print(res)
    24. # 模糊查询, 查询出名字里含有s的数据contains(区分大小写)<br /> # res = models.User.objects.filter(name__contains='z').values('name', 'age')<br /> # print(res)
    25. # 模糊查询, 忽略大小写icontains
    26. # 以什么开头startswith<br /> # res = models.User.objects.filter(name__startswith='h')
    27. # 以什么结尾endswith<br /> # res = models.User.objects.filter(name__endswith='u')
    28. # 查询时间__month月 __year年<br /> # res = models.User.objects.filter(register_time__month='1')
    29. # res = models.User.objects.filter(register_time__year='2020')
    30. # 一对多外键增删改查<br /> # 增<br /> # 1. 直接写实际字段publish_id = 1<br /> # models.Book.objects.create(name='你真好', price=123, publish_id=1)<br /> # models.Book.objects.create(name='三国演义', price=444, publish_id=2)<br /> # models.Book.objects.create(name='水浒传', price=555, publish_id=3)<br /> # 2. 写虚拟字段 = 对象 传对象<br /> # publish_obj = models.Publisher.objects.filter(pk=3).first()<br /> # models.Book.objects.create(name='呐喊', price=666, publish=publish_obj)
    31. # 删除<br /> # models.Book.objects.filter(name='你真好').delete()
    32. # 改<br /> # models.Book.objects.filter(name='呐喊').update(price='69.9')
    33. # 多对多外键增删改查<br /> # 给书籍添加作者, 可以使用数字, 也可以使用对象<br /> # 给地第三张关系表添加数据可以是数字和对象<br /> # book_obj = models.Book.objects.filter(pk=3).first()<br /> # book_obj.authors.add(1, 4)
    34. # author_obj = models.Author.objects.filter(pk=3).first()<br /> # book_obj.authors.add(author_obj)
    35. # 删除 remove()括号内既可以传数字也可以传对象, 支持多个<br /> # book_obj = models.Book.objects.filter(pk=4).first()<br /> # book_obj.authors.remove(1)
    36. # 改 set 括号内需要传递可迭代对象,支持多个, 对象内既可以是数字也可以是对象<br /> # book_obj = models.Book.objects.filter(pk=4).first()<br /> # book_obj.authors.set([1, 2])
    37. # 清空 clear() 括号内不要加任何参数<br /> # 在第三张表中清空某个书籍与作者的关系
    38. # book_obj.authors.clear()
    39. # 正向查询按字段, 反向查询按表名小写
    40. # 多表查询<br /> # 子查询(基于对象的跨表查询)<br /> # 正向<br /> # 1.查询书籍主键为2的出版社<br /> # book_obj = models.Book.objects.filter(pk=2).first()<br /> # res = book_obj.publish.name<br /> # print(res)<br /> # 反向<br /> # publish_obj = models.Publisher.objects.filter(book__pk=2).first()<br /> # print(publish_obj.name)<br /> # 2.查询书籍主键为2的作者<br /> # book_obj = models.Book.objects.filter(pk=2).first()<br /> # res = book_obj.authors.all()<br /> # print(res)
    41. # 3.查询作者jason的电话号码<br /> # author_obj = models.Author.objects.filter(name='jason').first()<br /> # res = author_obj.author_details # AuthorDetail表对象<br /> # print(res.phone)
    42. """<br /> 结论:<br /> 如果查询结果为多个的需要加上.all()方法<br /> 为单个的不需要, 直接拿数据对象<br /> """<br /> # 反向(反向用表名小写)<br /> # 4.查询出版社是东方出版社出版的书<br /> # publish_obj = models.Publisher.objects.filter(name='清华出版社').first()<br /> # res = publish_obj.book_set # app01.Book.None<br /> # 查询结果为多个需要加上.all()<br /> # res = publish_obj.book_set.all()<br /> # print(res)
    43. # 5.查询作者是jason写过的书<br /> # author_obj = models.Author.objects.filter(name='jason').first()<br /> # res = author_obj.book_set.all()<br /> # print(res)
    44. # 6.查询手机号是110的作者姓名<br /> # author_detail_obj = models.AuthorDetail.objects.filter(phone='123213213').first()<br /> # res = author_detail_obj.author<br /> # print(res.name)
    45. """<br /> 总结: 反向查询时:<br /> 当查询结果有多个是需要加上_set.all(), 返回queryset对象<br /> 查询结果为单个的时候不需要加, 直接返回对象<br /> """
    46. # 联表查询(基于双下划线的跨表查询)<br /> # 1.查询jason的手机号和作者姓名<br /> # 正向<br /> # res = models.Author.objects.filter(name='jason').values('author_details__phone', 'name')<br /> # print(res)<br /> # 反向基于AuthorDetail表查询<br /> # res = models.AuthorDetail.objects.filter(author__name='jason').values('phone', 'author__name')<br /> # print(res)
    47. # 2.查询书籍主键为2的出版社名称和书的名称<br /> # 正向<br /> # res = models.Book.objects.filter(pk=2).values('publish__name', 'name')<br /> # print(res)<br /> # 反向<br /> # res = models.Publisher.objects.filter(book__pk=2).values('name', 'book__name')<br /> # print(res)
    48. # 3.查询书籍主键为2的作者姓名<br /> # 正向<br /> # res = models.Book.objects.filter(pk=2).values('authors__name')<br /> # print(res)<br /> # 反向<br /> # res = models.Author.objects.filter(book__pk=2).values('name') # 拿写了书籍pk=2的作者详情<br /> # print(res)<br /> # 4.查询书籍主键是2的作者的手机号<br /> # 正向<br /> # res = models.Book.objects.filter(pk=2).values('authors__author_details__phone') # 书籍>作者>作者详情<br /> # print(res)
    49. # 反向<br /> # res = models.Author.objects.filter(book__pk=2).values('author_details__phone')<br /> # print(res)
    50. # 聚合查询 aggregate<br /> # from django.db.models import Max, Min, Count, Sum, Avg<br /> #<br /> # # 上诉方法一次性使用<br /> # res = models.Book.objects.aggregate(Max('price'), Min('price'), Count('pk'), Sum('price'), Avg('price'))<br /> # print(res)
    51. # 分组查询 annotate<br /> from django.db.models import Max, Min, Count, Sum, Avg
    52. # # 1. 统计每一本书的作者个数<br /> # res = models.Book.objects.annotate(author_sum=Count('authors')).values('name', 'author_sum')<br /> # print(res)<br /> '''<br /> author_sum是自定义的字段, 用来统计作者的个数<br /> '''<br /> # 2.统计每个出版社卖的最便宜的书的价格<br /> # res = models.Publisher.objects.annotate(min_price=Min('book__price')).values('name', 'min_price')<br /> # print(res)
    53. # 3.统计不止一个作者的图书<br /> # res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('name', 'author_num')<br /> # print(res)<br /> """<br /> 只要你的orm语句得出的结果还是queryset对象<br /> name他就可以继续无限制的点queryset方法<br /> """<br /> # 4.查询每个作者出的书的总价格<br /> # res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('name', 'sum_price')<br /> # print(res)
    54. """<br /> 按照指定字段分组<br /> models.Book.objects.values(字段).annotate()<br /> """
    55. # F 与 Q查询<br /> # F查询: 能够帮你直接获取表中某个字段的对应的数据<br /> from django.db.models import F, Q
    56. # 1. 查询销售额大于库存的书籍<br /> # res = models.Book.objects.filter(sales__gt=F('store')).values('name', 'sales', 'store')<br /> # print(res)<br /> # print(type(F('store')))
    57. # 2,将所有书籍价格提升500块<br /> # res = models.Book.objects.update(price=F('price')+500)<br /> # print(res)
    58. # 3.将所有数的名称后面加上爆款<br /> """<br /> 在操作字符类型的数据的时候, F不能直接做字符串的拼接<br /> """<br /> # from django.db.models.functions import Concat<br /> # from django.db.models import Value<br /> #<br /> # models.Book.objects.update(name=Concat(F('name'), Value('(爆款)')))
    59. # Q查询 (逗号, 和), (| 或), (~ 非)<br /> # 1.查询卖出数大于100或者价格小于600的书籍<br /> # res = models.Book.objects.filter(Q(sales__gt=100)|Q(price__lt=600)).values('name', 'price', 'sales')<br /> # print(res)
    60. # Q的高阶用法, 能够将查询条件的左边也变成字符串<br /> # q = Q()<br /> # # 连接方式<br /> # q.connector = 'or' # 默认还是and关系<br /> # q.children.append(('sales__gt', 100))<br /> # q.children.append(('price__lt', 600))<br /> # res = models.Book.objects.filter(q)<br /> # print(res)
    61. # django中如何开启事务<br /> """<br /> 事务的四大特性: ACID<br /> 原子性<br /> 不可分割的最小单位<br /> 一致性<br /> 跟原子性相辅相成<br /> 隔离性<br /> 事务之间互不干扰<br /> 持久性<br /> 事务一旦确认永久生效<br /> 事务的回滚<br /> rollback<br /> 事务的确认<br /> commit<br /> <br /> """<br /> # django中如何开启简单的事务<br /> """<br /> from django.db import transaction<br /> try:<br /> with transaction.atomic():<br /> pass<br /> # spl<br /> # spl<br /> except Exception as e:<br /> print(e)<br /> print('执行其他操作')<br /> """
    62. # orm中常用字段和参数<br /> """<br /> AutoField 主键字段 primary_key = True<br /> <br /> CharField varchar max_length 长度, verbose_name 字段的注释<br /> <br /> IntegerField int<br /> <br /> BigIntegerField bigint<br /> <br /> DecimalField 浮点数 max_digits 值的总长度 decimal_places小数点后的长度<br /> <br /> EmailField varchar(254)<br /> <br /> DateField date<br /> DatetimeField datetime<br /> auto_now: 每次修改数据的时候会自动更新当前的时间<br /> auto_now_add: 只在创建数据的时候记录创建时间, 后面不会再自动改变<br /> <br /> BooleanField 布尔值类型 数据库里面传0/1(False/True)<br /> <br /> TextField 文本类型 没有字数限制, 可以用来存放大文章<br /> <br /> FileField 字符类型 upload_to = '/xxx'<br /> 给该字段传一个文件对象, 会自动将文件保存到/xxx文件夹下, 然后将文件路径存入数据库<br /> <br /> 自定义生成字段类型<br /> class MyCharField(models.Field):<br /> def __init__(self,max_length,*args,**kwargs):<br /> self.max_length = max_length<br /> # 调用父类的init方法<br /> super().__init__(max_length=max_length,*args,**kwargs) # 一定要是关键字的形式传入
    63. def db_type(self, connection):<br /> <br /> # 返回真正的数据类型及各种约束条件<br /> :param connection:<br /> :return:<br /> return 'char(%s)'%self.max_length
    64. # 自定义字段使用<br /> myfield = MyCharField(max_length=16,null=True)<br /> <br /> <br /> 外键字段及参数<br /> ForeignKey(unique=True) === OneToOneField()(推荐使用)<br /> <br /> db_index: db_index=True 则代表为该字段设置索引 <br /> <br /> to_field: 设置要关联的表的子弹 默认不写关联的就是另外一张表的主键<br /> <br /> on_delete: 当删除表的时候吗当前表与其关联表的行为<br /> <br /> django2.x以上额版本需要自己设置, 1.x默认为级联删除<br /> <br />"""
    65. # 数据库查询优化<br /> # only与defer<br /> # select_related与prefetch_repated<br /> # orm语句的特点, 惰性查询<br /> # 如果你仅仅是指书写了orm语句, 在后面没有使用到查询出来的参数, orm会自动识别 直接不执行
    66. # only与defer<br /> # 想要获取书籍表中所有书的名字<br /> # res = models.Book.objects.values('name')<br /> # for i in res:<br /> # print(i.get('name'))
    67. # res = models.Book.objects.only('name')<br /> # res = models.Book.objects.all()<br /> # for i in res:<br /> # print(i.name) # 获取only括号内的字段不会再查询数据库<br /> # print(i.price) # 获only括号内没有的字段, 会重新走数据库查询, 而all不需要走了
    68. # defer: 与only正好相反, 括号内的需要在查一遍, 括号外的不需要再查一遍<br /> # res = models.Book.objects.defer('price')<br /> # for i in res:<br /> # print(i.name)<br /> # print(i.price)
    69. # select_related与prefetch_related 这两个和跨表操作有关<br /> # res = models.Book.objects.all()<br /> # for i in res:<br /> # print(i.publish.name) # 通过book对象查询出版社对象, 每循环一次都要查询次数据库
    70. # res = models.Book.objects.select_related('publish') # inner join<br /> # print(res)<br /> # for i in res:<br /> # print(i.publish.name)
    71. """<br /> selected_related内部直接先将book和publisher表连接起来, 将两张表的数据全部封装给查询出来的对象<br /> 这是时候无论点击book表中的数据还是publisher表中的数据都不需要再查一遍<br /> """
    72. # prefetch_related 子查询<br /> # res = models.Book.objects.prefetch_related('publish')<br /> # for i in res:<br /> # print(i.name)
    73. """<br /> prefetch_related内部就是子查询, 将子查询出来的结果也封装到对象中, 给你的感觉好像是一次性搞定的<br /> """