测试环境

  1. import os
  2. if __name__ == "__main__":
  3. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day64.settings")
  4. import django
  5. django.setup()
  6. 下面继续书写脚本代码

前识回顾:

  1. import os
  2. if __name__ == "__main__":
  3. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day64.settings")
  4. import django
  5. django.setup()
  6. from app91 import models
  7. import datetime
  8. #增
  9. # 方式一
  10. # models.User.objects.create(name='wyy',age=19,register_time='2021-2-8 8:00:00')
  11. #方式二
  12. # user_obj = models.User(name='lili',age=56,register_time=datetime.datetime.now())
  13. # user_obj.save()
  14. # 删
  15. # 方式一
  16. # models.User.objects.filter(pk =1).delete()
  17. # 方式二
  18. # user_obj = models.User.objects.filter(pk = 1).first()
  19. # user_obj.delete()
  20. # 改
  21. # 方式一
  22. # models.User.objects.filter(pk = 1).update(name='lala')
  23. # 方式二
  24. # user_obj = models.User.objects.get(pk = 1) #该方法不推荐使用,如果pk不存在则会直接报错,而filter则不会
  25. # user_obj.name = 'heihei'
  26. # user_obj.save()

查看内部sql语句的方式
.query 只能用于queryset

通用方式:在配置内加配置

  1. LOGGING = {
  2. 'version': 1,
  3. 'disable_existing_loggers': False,
  4. 'handlers': {
  5. 'console':{
  6. 'level':'DEBUG',
  7. 'class':'logging.StreamHandler',
  8. },
  9. },
  10. 'loggers': {
  11. 'django.db.backends': {
  12. 'handlers': ['console'],
  13. 'propagate': True,
  14. 'level':'DEBUG',
  15. },
  16. }
  17. }

必会13条

  1. # 1.all() 查询所有
  2. # 2.filter 带有过滤条件的查询
  3. # 3.get 直接拿数据对象,条件不存在时直接报错
  4. # 4.first 拿queryset内第一个元素
  5. # 5.last 拿queryset内最后一个元素
  6. # 6.values 拿取一个或多个字段对应的值
  7. # models.User.objects.values('name','age')
  8. # 类似于 select name,age from ...;
  9. #返回的是[{},{}]
  10. # 7.values_list
  11. # models.User.objects.values_list()
  12. #返回的是[(),()]
  13. # 8.distinct 去重,要把主键排除在外,否则无法去重
  14. # models.User.objects.values('name','age').distinct()
  15. # 9.order_by 排序
  16. # models.User.objects.order_by('age') #默认升序
  17. # models.User.objects.order_by('-age') #降序
  18. # 10.reverse 反转的前提是数据已经排序
  19. # 11.count 统计个数
  20. #models.User.objects.all().count()
  21. # 12.exclude 排除某个在外
  22. # models.User.objects.exclude(name='wyy')
  23. # 13.exists 判断是否存在

双下划线查询

  1. # models.User.objects.filter(age__gt=20) 大于
  2. # models.User.objects.filter(age__lt=20) 小于
  3. # models.User.objects.filter(age__lte=20) 小于等于
  4. # models.User.objects.filter(age__gte=20) 大于等于
  5. # models.User.objects.filter(age__in=[10,20,30]) 查询年龄是10,20,30的数据
  6. # models.User.objects.filter(age__range=[10,30]) 查询年龄在10-30之间的数据,收尾兼顾
  7. # models.User.objects.filter(name__contains='n') 查询名字包含n的数据 区分大小写
  8. # models.User.objects.filter(name__icontains='n') 查询名字包含n的数据 忽略大小写
  9. # models.User.objects.filter(name__endswith='w') 查询名字以w结尾的数据,startwith同理
  10. # models.User.objects.filter(register_time__year='2021') 查询时间以年份为单位查询,月、日.....同理

外键增删改查

  1. #外建增删改查
  2. # 一对多
  3. # 增
  4. # models.Book.objects.create(titlle='',price='',publish_id=值)
  5. # models.Book.objects.create(titlle='',price='',publish=对象)
  6. # 删
  7. # models.Publish.objects.filter().delete() 级联删除
  8. # 修改
  9. # 修改一样可以和增加一样直接给值或者给对象
  10. # 多对多 第三张关系表的增删改查
  11. # 增
  12. # 书籍表和作者表
  13. # Book_obj = models.Book.objects.filter(pk=1).first()
  14. #
  15. # Book_obj.authors.add(1,2) 主键为1的书籍添加作者主键为1和2,以此操作第三张表
  16. #
  17. # author_obj = models.author.objects.filter(pk= 1).first()
  18. # Book_obj.authors.add(author_obj) 对象可放多个
  19. #
  20. # add:给第三张关系表添加数据,括号内既可以传值,也可以传对象,支持多个
  21. #
  22. #
  23. #
  24. #
  25. # 删
  26. #
  27. # Book_obj.authors.remove(1,2) 同样支持传值和对象
  28. #
  29. # remove 第三张关系表删除数据,括号内既可以传值,也可以传对象,支持多个
  30. #
  31. #
  32. # 改
  33. #
  34. # Book_obj.authors.set([1,2])
  35. #
  36. # set 括号内必须是可迭代对象,既可以是对象也可以是值,同样支持多个
  37. # 先删除,后新增的方式修改
  38. #
  39. #
  40. # 清空
  41. #
  42. # 在第三张表内清空两者绑定关系
  43. #
  44. # Book_obj.authors.clear() 清空Book_obj绑定的所有关系

正反向的跨表查询

  1. 正反向概念
  2. 看外键字段在哪张表,有外键字段查询没有外键字段的,为正向,反之则为反向
  3. 正向查询按字段
  4. 反向查询按表名小写
  5. 跨表查询
  6. 基于对象(子查询)
  7. 正向
  8. 查询书籍主键为1的出版社
  9. Book_obj = models.book.objects.filter(pk=1).first()
  10. Book_obj.publish.all().name 获取出版社名字 能拿到多个,则要.all()
  11. Book_obj.publish.addr 获取出版社地址
  12. 反向
  13. 查询出版社出版了哪些书
  14. publish_obj = models.Publish.objects.filter(name='北京出版社').first()
  15. publish_obj.book_set.all()
  16. 总结:
  17. 当反向查询结果有多个需要在表名后加_set.all(),一个则不需要
  18. 基于双下划线(联表查询)
  19. 查询书籍主键为1的出版社名称和书的名称
  20. models.book.objects.filter(pk =1).values('title','publish__name')
  21. title book表内直接写,出版社名称在另外一张表,直接publish__name
  22. models.Publish.objects.filter(book__id=1).values('name','book__title')
  23. 上述正反向结果一致
  24. 查询书籍主键为1的作者的电话号码
  25. models.Book.objects.filter(pk=1).values('author__author_detail__phone')

聚合查询

  1. # 聚合查询 aggregate(单独使用的时候用的关键字)
  2. from django.db.models import Min,Max,Sum,Count,Avg
  3. from app91 import models
  4. models.Book.objects.aggregate(Avg('price'),Max('price'),Min('price'),Count('pk'),Sum('price'))

分组查询

  1. 分组查询 annotate
  2. models.Book.objects.annotate() 按书分组
  3. models.Book.objects.annotate(author_num=Count('authors')).values('title','author_num')
  4. models.Book.objects.values('price').annotate() 按照表中指定字段进行分组
  5. 分组查询如果出错,记得查看严格模式

F与Q查询

  1. F查询
  2. from django.db.models import F
  3. models.Book.objects.filter(salesnum__gt=F('inventory')) 查询销售数量大于库存数量的书籍
  4. models.Book.objects.update(price=F('price')+10) 给书籍表中所有书籍价格加10
  5. Q查询
  6. from django.db.models import Q
  7. models.Book.objects.filter(Q(salesnum__gt=100),Q(price__gt=20)) 默认and关系
  8. models.Book.objects.filter(Q(salesnum__gt=100)|Q(price__gt=20)) or关系
  9. models.Book.objects.filter(~Q(salesnum__gt=100)|Q(price__gt=20)) 非关系
  10. Q高阶用法
  11. q=Q()
  12. q.connector='or' 改成or连接
  13. q.children.append('salenum__gt',100)
  14. q.children.append('price__gt',20)
  15. models.Book.objects.filter(q) 等同于上面的and关系查询

django中开启事务

  1. from django.db import transaction
  2. with transaction.atomic():
  3. sql1
  4. sql2
  5. sql3.....
  6. with下书写的sql都属于同一个事务

choices参数

  1. # choices参数
  2. # 只要某个字段可能性能列举完全的,一般情况下都会采用choices参数
  3. #
  4. class User(models.Model):
  5. name = models.CharField(max_length=32)
  6. age = models.IntegerField()
  7. gender_choices =(
  8. (1,'男'),
  9. (2,'女'),
  10. (3,'其他'),
  11. )
  12. gender = models.IntegerField(choices=gender_choices)
  13. #gender中存到数字在上面的gender_choices中,会自动匹配到对应关系
  14. #不在范围内照样存储
  15. models.User.objects.filter(pk=1).first().get_gender_display()
  16. 取值方法:get_XXX_display() XXX为字段名
  17. 如果没有对应关系则直接返回存储的值