Django_day04

聚合查询

# 聚合查询
    '''聚合查询通常情况下都是配合分组一起使用的
    只要是跟数据库相关的模块
            基本上都在django.db.models里面
            如果上述没有那么应该在django.db里面'''
    from django.db.models import Max,Min,Sum,Count,Avg      # 模块的导入
    # 1. 所有书的平均价格
    # res = models.Book.objects.aggregate(Avg('price'))
    # print(res)
    # 2.上述方法一次性使用
    res = models.Book.objects.aggregate(Max('price'), Min('price'), Sum('price'), Count('price'), Avg('price'))
    print(res)

分组查询

# 分组查询      annotate
    '''
        MySQL分组查询都有哪些特点
            分组之后默认只能获取到分组的依据 组内其它字段都无法直接获取了
                严格模式
                    ONLY_FULL_GROUP_BY
                    '''
    from django.db.models import Max, Min, Sum, Count, Avg
    1.统计每一本书的作者个数
    res = models.Book.objects.annotate()        # models后面.什么就是按什么分组  这句话意思就是按照书分组
    res = models.Book.objects.annotate(author_num=Count('authors')).values('title', 'author_num')
    print(res)
    2.统计每个出版社卖的最便宜的书的价格
    res = models.Publish.objects.annotate(min_book=Min('book__price')).values('name', 'min_book', 'book__title')
    print(res)
    3.统计不止一个作者的图书
    res = models.Book.objects.annotate(author__num=Count('authors')).filter(author__num__gt=1).values('title','author__num')
    print(res)
    '''
        只要你orm语句得出的结果还是一个 queryset对象
        那么它就能无限制的点 queryset对象封装的方法   
    '''
    4.查询每个作者出的书的总价格
    res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('name', 'sum_price')
    print(res)
    '''
        如果你想按照指定的字段进行分组
            models.Book.objects.values('price').annotate()
            
        你们的机器上 
    '''

F与Q查询

 # F与Q查询
    # 1. 查询卖出数大于库存数的书籍
    # F查询
    '''
    能够直接帮你获取到表中某个字段对应的数据
    '''
    from django.db.models import F
    # res = models.Book.objects.filter(maichu__gt=F('kucun'))
    # print(res)
    # 2.将所有的书籍的价格提升50块
    # models.Book.objects.update(price=F('price')-50)
    # 3.将所有的书的名称后面加上爆款两字
    '''
    在操作字符类型的数据的时候  F不能够直接做到字符串的拼接
    '''
    from django.db.models.functions import Concat
    from django.db.models import Value
    models.Book.objects.update(title=Concat(F('title'),Value('(爆款)')))
     '''
     models.Book.objects.update(title=F('title')+'(爆款)'))  这样会直接让你的所有名称变空白(django1.x版本会 2.x及以上不会)
     '''

 # Q查询
    # 1. 查询卖出数大于100 或者 价格小于600 的书籍

    res = models.Book.objects.filter(maichu__gt=950,price__lt=180).values('title')
    '''
        filter括号内 多个参数默认的是 and 关系 
    '''
    from django.db.models import Q
    res = models.Book.objects.filter(Q(maichu__gt=950) | Q(price__lt=180)).values('title')  # 导入Q模块后 用Q()包裹起来 就可以用关系符了  | 或
    res = models.Book.objects.filter(Q(maichu__gt=950) , Q(price__lt=180)).values('title')  # , 还是and关系
    res = models.Book.objects.filter(~Q(maichu__gt=950) | Q(price__lt=180)).values('title')  # ~ not关系
    print(res)

    # Q的高阶用法    能够将查询条件的左边也变成可以改变的字符串的形式 不局限于字段
    q = Q()
    q.connector = 'or'      # 默认关系是 and 可以这样修改成 or
    q.children.append(('maichu__gt', 950))
    q.children.append(('price__lt', 180))
    res = models.Book.objects.filter(q)
    print(res)

django中如何开启事务

事务 
	ACID  四个特性
		原子性
			不可分割的最小的单位
		一致性
			跟原子性是相辅相成的
		隔离性
			事务之间互相不干扰
		持久性
			事物一旦确认永久生效
		
	事务的回滚
		rollback
	事务的确认
		commit
	
'''
目前你只需要所掌握Django中如何简单的开启事务
	

orm中常用字段及参数

AutoField
	主键字段 primary_key=True
CharField			对应数据库的是varchar
	verbose_name	字段的注释
	max_length		长度

IntegerField		int
BigIntegerField		bigint

DecimalField		DecimalField(max_digits=8, decimal_places=2)     # 小数 一共八位  小数点后面占两位

EmailField			varchar(254)

DateField			date
DateTimeField		datetime
	auto_now:每次修改数据的时候都会自动更新当前时间
	auto_now_add:只在创建数据的时候记录创建的时间 后续不会自动修改了

BooleanField(Field)				-布尔值类型
	该字段传布尔值(False/True)	数据库里面存0/1

TextField			- 文本类型
	该字段可以用来存大段内容(文字、博客..)
	后面的bbs作业  文章字段用的就是TextField

FileField
	upload_to = '/data' 给该字段传一个文件对象, 会自动将文件保存到/data 目录下
	然后将文件路径保存到数据库中
	/data/a.txt
	后面的bbs作业也会涉及
		
https://www.cnblogs.com/Dominic-Ji/p/9203990.html


'''django除了给你提供了很多字段类型外 还支持你自定义字段'''
class MyCharField(models.Field):
    def __init__(self, max_length, *args, **kwargs):
        self.max_length = max_length
        # 调用父类方法
        super().__init__(max_length=max_length, *args, **kwargs) # 一定要是关键字的形式传入


    def db_type(self, connection):
        '''
        这返回的才是真正的 数据类型及各种约束条件
        :param connection:
        :return:
        '''
        return 'char(%s)' % self.max_length

'''自定义字段的使用'''
myfiled = MyCharField(max_length=13, null=True)

数据库查询优化

only与defer
select_related 与 prefetch_related

'''
orm语句的特点:
	惰性查询
		如果你仅仅只是书写了orm语句 在后面根本没有用到该语句所查询出来的参数
		那么orm会自动识别 直接不执行
'''


# only与defer
res = models.Book.objects.all()
    print(res)

    想要获取书籍表中所有书籍的名字
    res = models.Book.objects.values('title')
    print(res)
    for t in res:
        print(t.get('title'))
    实现获取到的是一个数据对象  然后点title的方式能够拿到书名 并且没有其它字段
    res = models.Book.objects.only('title')
    print(res)                  # <QuerySet [<Book: Book object (1)>, <Book: Book object (2)>, <Book: Book object (3)>, <Book: Book object (4)>, <Book: Book object (5)>]>
    for t in res:
        print(t.title)          # 点击only括号内的字段 不会走数据库
        print(t.price)          # 点击only括号内没有的字段 会重新走数据库查询

    res = models.Book.objects.defer('title')        # 对象除了没有title属性外其它都有
    # print(res)
    for t in res:
        print(t.price)
    '''
        defer 和 only 刚好相反
            defer括号内的不在查询出来的对象里面  该字段的查询需要重新走数据库
    '''

choices参数(数据库字段设计常见)

'''
用户表
	性别
	学历
	工作经验
	是否结合
	客户来源
	...
针对某个可以列举完全的可能性字段, 我们应该如何存储

只要某个字段的可能性是可以列举完全的,那么一般情况下都会采用choices参数
'''
class User(models.Model):
    username = models.CharField(max_length=32)
    age = models.IntegerField()
    # 性别
    gender_choices = (
        (1,'男'),
        (2,'女'),
        (3,'其它'),
    )
    gender = models.IntegerField(choices=gender_choices)        # choices 固定写法

    score_choices = (
        ('A','优秀'),
        ('B','良好'),
        ('C','及格'),
        ('D','不合格'),
    )
    score = models.CharField(choices=score_choices, null=True)

    '''
    该gender字段存的还是数字 但是如果存的数字在上面元组列举的范围之内
    那么可以非常轻松的获取到数字对应的内容
    
    1.gender字段存的数字不在上述元组列举的范围之内
    2.如果在如何获取对应中文信息
    '''

from app01 import models
    models.User.objects.create(username='jason', age=19, gender=1)
    models.User.objects.create(username='egon', age=85, gender=2)
    models.User.objects.create(username='tank', age=40, gender=3)
    models.User.objects.create(username='tony', age=49, gender=4)


    # 取
    user_obj = models.User.objects.filter(pk=1).first()
    print(user_obj.gender)
    # 要获取 choices参数的字段 固定写法
    print(user_obj.get_gender_display())

    user_obj = models.User.objects.filter(pk=4).first()
    # 如果choices里面没有对应关系  那么就是该gender原本的值
    print(user_obj.get_gender_display())


MTV与MVC模型

MTV: Django号称是MTV模型
M:models
T:templates
V:views;
	
MVC: 其实django本质也是MVC
M:models
V:views
C:controller(urls.py)

多对多三种创建方式

全自动:利用orm自动帮我们创建第三张表
	class Book(models.Model):
    name = models.CharField(max_length=32)
    authors = models.ManyToManyField('Author', on_delete=models.CASCADE)


	class Author(models.Model):
    name = models.CharField(max_length=32)
'''
	有点 : 代码不需要你写  非常的方便 还支持orm提供操作的第三张表的方法
	不足之处: 第三张关系表的扩展性极差(没有办法额外添加字段)
'''
# 纯手动
class Book(models.Model):
    name = models.CharField(max_length=32)
    authors = models.ManyToManyField('Author', on_delete=models.CASCADE)


	class Author(models.Model):
    name = models.CharField(max_length=32)

	class Book2Author(models.Model):
		book_id = models.ForeignKey('Book', on_delete=models.CASCADE)
		author_id = models.ForeignKey('Author', on_delete=models.CASCADE)
	'''
	优点: 第三张表完全取决于你自己进行额外的扩展
	不足之处:需要写的代码较多, 不能够再使用orm提供的方法
	'''
   
# 半自动

class Book(models.Model):
    name = models.CharField(max_length=32)
    authors = models.ManyToManyField('Author', on_delete=models.CASCADE,
                                     through='Book2',
                                     through_fields=('book', 'author'))


class Author(models.Model):
    name = models.CharField(max_length=32)


class Book2(models.Model):
    book = models.ForeignKey('Book', on_delete=models.CASCADE)
    author = models.ForeignKey('Author', on_delete=models.CASCADE)

'''
through_fields字段先后顺序
    判断本质:
        通过第三张表查询对应的表 需要用到哪个字段就把哪个字段放前面

半自动:可以使用orm正反向查询 但是没法使用add,set,remove,clear这四个方法 
'''

ajax

'''
异步提交
局部刷新

参考案例:github注册实时获取用户名发送给后端确认并动态展示校验结果(页面不刷新)

复习: input框实时监测事件  input事件

'''

# ajax基本语法
$.ajax({
	url:'',		# 朝后端哪个地址发送  不写就是默认朝当前地址发送	跟action三种书写方式一致
	type:'get/post',	# 提交方式 默认get 跟form表单提交方式一致
	data:{'username':'jason','password':123},		#要发送的参数
	success:function(args){
		# 异步回调处理机制
		
	}	
})
'''
当你在利用ajax进行前后端交互的时候
后端无论返回什么  都只会被回调函数接收 而不再影响这个浏览器页面了
'''

# 扩展 参数
dataType:'JSON'
'''
当后端是以HttpResponse返回的json格式的数据
默认是不会自动反序列化的
	1.自己手动 JSON.parse()
	2.配置dataType参数
'''
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值