django 中的聚合和分组 F查询 Q查询 事务cookies和sessions 066
1 聚合和分组
聚合:对一些数据进行整理分析 进而得到结果(mysql中的聚合函数)
1aggregate(*args,**kwargs) :
通过对QuerySet进行计算 ,返回一个聚合值的字典.其中每一个参数都指定一个包含在字典中的返回值.即在查询集上生成聚合
from django.db.models import Avg,Min,Sum,Max
# 从整个查询集生成统计值.比如,你想要计算所有在售书籍的平均价钱.django的查询语法提供了一种方式描述所有图书的集合
Book.objects.all().aggregate(Avg('price'))
#{'print_avg':34.35}
#aggregate()字句的参数描述了我们想要计算的聚合值 它是一个终止字句.意思是说,他返回一个包含一些键值对的字典 键的名称是按照字段和聚合函数的名称自动生成出来的如果想指定一个名称 可以按照这样的方式命名:
Book.objects.aggregate(average_price=Avg('price'))
#也可以查询多个值 即想知道所有图书价格的最大值和最小值 也可以
Book.objects.aggregate(Avg('price'),Max('price'),Min('price'))
分组:annotate(*args,**kwargs)
可以通过查询结果中每一个对象 所关联的对象集合,从而得出总计值(也可以是平均值或者总和),即为查询集的每一项生成聚合
#案例1:查询卢俊义出的书的总价格
Boo.objects.filter(author__name='卢俊义').aggregate(Sum('price'))
#案例2:查各个作者出的书的总价格 这就涉及到分组了,条件是authors__name
Book.objects.values('authors__name').annotate(Sum('price'))
#案例3:查询各个出版社最便宜的书的价格
Book.objects.values('publisher__name').annotate(Min('price'))
F查询和Q查询
首先需要导入F
from django.db.models import F
#第一种用法 查询 可以结合前边的基于字段或者正反向查询都可以实现
# 动态的获取字段的值 比较表格中两列的值
ret = models.Book.objects.filter(kucun__gt =F('sale')).values()
#该语句想要获取的是库存量大于销售量的书籍 # 第二种用法:对某列数据进行操作
#刷单 提高书籍的销售量 但是不改变库存 将某一列进行批量操作
modles.Book.objects.update(sale=F('sale')*2)
# 此语句可以将书籍销量那一列进行更新 # 也可以进行单列更新
obj = models.Book.objects.filter(id=1).first()
obj.sale = 60
obj.save() update和save()的区别
#前者只是对限制查询的列表列字段进行更新修改 而save是将所有的字段都
#进行了一遍的更新 因此欠着的效率要比后者高一点点 前者也可以实现后者
#的功能 即在前边加一个all() 就实现了全部刷新 即
models.Book.objects.all().update(sale=1000)
#可实现对表格的所有的字段进行刷新
Q查询
首先需要导入Q
from django.db.models import Q
#构建Q的搜素条件
from django.db.models import Q
# 1 Q对象(django.db.models.Q)可以对关键字参数进行封装,从而更好地应用多个查询
q1 = models.Book.objects.filter(Q(title__startswith='P')).all()
print(q1) #[<Book:Python>,<Book:Perl>] #2 可以组合使用&(和),|(或)操作符,当一个操作符是用于两个Q的对象,它产生一个新的Q对象
Q(title__startswith='P') | Q(title__startswith='J')
# 获取以P或者J开头的所有的对象 #3 Q对象可以用~操作符放在前面表示否定 也可以允许否定与不否定形式的足额
Q(title__startswith='P') |~Q(pub_date__year=2005)
查询以P开头的或者出版日期不是2005年的书籍 #4 应用范围:
# Each lookup function that takes keyword-arguments (e.g. filter(),
# exclude(), get()) can also be passed one or more Q objects as
# positional (not-named) arguments. If you provide multiple Q object
# arguments to a lookup function, the arguments will be “AND”ed
# together. For example: Book.objects.get(
Q(title__startswith='P'),
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
) # sql:
# SELECT * from polls WHERE title LIKE 'P%'
# AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06') # import datetime
# e=datetime.date(2005,5,6) #2005-05-06
#5Q对象可以和关键字参数查询一起使用 不过一定要把Q对象放在关键字参数查询的前面
事务
一系列的操作要么同时成功执行要么都不执行 保证原子性操作
from app01 import models from django.db import transaction try:
with transaction.atomic():
models.Publisher.objects.create(name='新华出版社1')
int('aaa')
models.Publisher.objects.create(name='新华出版社2')
models.Publisher.objects.create(name='新华出版社2')
except Exception as e:
print(e) #此时会走e
#错误信息为 invalid literal for int() with base 10: 'aaa'
cookie
定义:保存在浏览器上的一组组键值对 是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器的时候浏览器会自动携带这些键值对 下次访问服务器的时候浏览器会自动携带这些键值对 以便服务器提取有用信息.
原理: 由服务器产生内容,浏览器接收后保存到本地,当浏览器再次访问时,浏览器会自动带上这些键值对 这样服务器就能通过cookie的内容来判断这个是谁了
特性:
1.服务器让浏览器保存的cookie
2.浏览器有权利进行不设置
3.下次访问时自动携带响应的cookie
django中操作cookie
1 获取cookie
request.COOKIES['key']
request.get_signed_cookie('key',default=RAISE_ERROR,salt='',max_age=None)
#get_signed_cookie方法的参数:
#default:默认值
#salt:加密盐
#max_age:后台控制过期时间
2 设置cookies
reo = HttpResponse(...)
rep = render(request,....)
rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密盐',.....) # 参数
#key,键
#value='',值
#max_age=None,超时时间
#expires=None,超时时间(IE requires expires,so set it if hasn't been already)
#path='/' cookie生效的路径 /表示根路径, 特殊的:根路径的cookie可以被任何url的页面访问
#domain=None,cookie生效的域名
secure=False,https传输
httponly=False 只能http协议传输 无法被js获取(不是绝对,底层抓包可以获取到也可以被覆盖)
3 删除cookie
def logout(request):
rep = redirect(/'login/')
rep.delete_cookie('user') # 删除用户浏览器上之前设置的user的cookoie值
return rep
4 案例 定义登录 通过cookie
# 做一个页面的访问之前的登录认证以及登录成功后直接进入之前要登录进入的页面
#流程 先登录 将登录信息以及cookie状态封装到装饰器里面再将装饰器加到要进入的页面上 从而实现登录才能访问某界面
# 先写装饰器
def login_required(func):
def inner(request, *args, **kwargs):
# 获取cookie
is_login = request.COOKIES.get('is_login') # 不加密的cookie
# 获取登录状态is_login = request.get_signed_cookie('is_login',salt='day66',default='xx') # 加密cookie return_url = request.path_info # 获取即将跳转的页面地址
if is_login == '':
ret = func(request, *args, **kwargs)
else:
ret = redirect('/login/?return_url={}'.format(return_url)) # login地址上携带上要跳转的地址
print(ret)
print(return_url)
return ret return inner #定义登录功能
def login(request):
if request.method == 'POST':
# 获取用户名和密码、要访问的页面
user = request.POST.get('user')
pwd = request.POST.get('pwd')
print(user)
return_url = request.GET.get('return_url') # 此处的路径由上边的装饰器处获取
print(return_url)
if user == 'alex' and pwd == '':
# 有跳转的地址时访问到跳转地址,否则访问index页面
if return_url:
ret = redirect(return_url)
else:
ret = redirect('/index/')
ret.set_cookie('is_login', '') # 设置cookie 超时时间 max_age=5 路径 path='/home/'
# ret.set_signed_cookie('is_login', '1', 'day66') # 设置加密cookie
return ret
return render(request, 'login.html') # 给响应页面加装饰器
@login_required
def index(request):
return HttpResponse('index') # 删除cookie
def logout(request):
ret = redirect('/login/')
# 删除cookie
ret.delete_cookie('is_login') # Set-Cookie: is_login=""; expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Path=/
return ret
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
<p>
用户名:<input type="text" name="user">
</p>
<p>
密码:<input type="password" name="pwd">
</p>
<button>登录</button>
</form>
</body>
</html>
session
cookie虽然在一定程度上解决了保持状态的需求 但是由于cookie本身最大支持4096字节 以及cookie本身保存在客户端 , 可能被拦截或窃取因此需要一种新的东西 能支持更多的字节,并且保存在服务器 有较高的安全性 即session
django中的session相关方法:
# 获取、设置、删除Session中数据
request.session['k1']
request.session.get('k1',None)
request.session['k1'] = 123
request.session.setdefault('k1',123) # 存在则不设置
del request.session['k1'] # 所有 键、值、键值对
request.session.keys()
request.session.values()
request.session.items()
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems() # 会话session的key
request.session.session_key # 将所有Session失效日期小于当前日期的数据删除
request.session.clear_expired() # 检查会话session的key在数据库中是否存在
request.session.exists("session_key") # 删除当前会话的所有Session数据
request.session.delete()
# 删除当前的会话数据并删除会话的Cookie。
request.session.flush()
这用于确保前面的会话数据不可以再次被用户的浏览器访问
例如,django.contrib.auth.logout() 函数中就会调用它。 # 设置会话Session和Cookie的超时时间
request.session.set_expiry(value)
* 如果value是个整数,session会在些秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。
django中的session配置
1. 数据库Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认) 2. 缓存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置 3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎
SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 4. 缓存+数据库
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎 5. 加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎 其他公用设置项:
SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认)
SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认)
SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认)
SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认)
SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认)
SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认) Django中Session相关设置
session登录案例
from django.shortcuts import render, redirect, HttpResponse
from django.conf import global_settings, settings
from django.contrib.sessions.backends import db def login_required(func):
def inner(request, *args, **kwargs):
# print(request.session.session_key) # 查看session的session_key
# print(request.session.exists('r0f6ys1wj4du94w0fzr5lapyoxxzqr93')) # 判断对应的数据是否存在
is_login = request.session.get('is_login') # 获取session
return_url = request.path_info
if is_login == '':
ret = func(request, *args, **kwargs)
else:
ret = redirect('/login/?return_url={}'.format(return_url))
return ret
return inner def login(request):
if request.method == 'POST':
user = request.POST.get('user')
pwd = request.POST.get('pwd')
print(user)
return_url = request.GET.get('return_url')
if user == 'alex' and pwd == '':
if return_url:
ret = redirect(return_url)
else:
ret = redirect('/index/')
request.session['is_login'] = ''
return ret
return render(request, 'login.html') @login_required
def home(request):
# is_login = request.COOKIES.get('is_login')
# if is_login != '1':
# return redirect('/login/')
return HttpResponse('home') @login_required
def index(request):
return HttpResponse('index') def logout(request):
# request.session.delete() # 删除服务器的session数据,不删除cookie
request.session.flush() # 删除session和cookie
ret = redirect('/login/')
# ret.delete_cookie('is_login') # Set-Cookie: is_login=""; expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Path=/
return ret
该案例将数据存放在mysql数据库中 ,可以在数据库中看到 扎样的数据 分别是session的钥匙和数据
django 中的聚合和分组 F查询 Q查询 事务cookies和sessions 066的更多相关文章
- Django 聚合分组F与Q查询及choices
一.聚合查询 需要导入模块:from django.db.models import Max, Min, Sum, Count, Avg 关键语法:aggregate(聚合结果别名 = 聚合函数(参数 ...
- django----聚合查询 分组 F与Q查询 字段 及其 参数
目录 一.orm补充查询 聚合查询 1-1 分组查询 1-2 F与Q查询 1-3 二. 字段及其参数 常用字段 AutoField IntegerField CharField DateField D ...
- ORM之自关联、add、set方法、聚合函数、F、Q查询和事务
一.外键自关联(一对多) 1.建表 # 评论表 class Comment(models.Model): id = models.AutoField(primary_key=True) content ...
- Django 08 Django模型基础3(关系表的数据操作、表关联对象的访问、多表查询、聚合、分组、F、Q查询)
Django 08 Django模型基础3(关系表的数据操作.表关联对象的访问.多表查询.聚合.分组.F.Q查询) 一.关系表的数据操作 #为了能方便学习,我们进入项目的idle中去执行我们的操作,通 ...
- Django 聚合查询 分组查询 F与Q查询
一.聚合查询 需要导入模块:from django.db.models import Max, Min, Sum, Count, Avg 关键语法:aggregate(聚合结果别名 = 聚合函数(参数 ...
- Django中多表的增删改查操作及聚合查询、F、Q查询
一.创建表 创建四个表:书籍,出版社,作者,作者详细信息 四个表之间关系:书籍和作者多对多,作者和作者详细信息一对一,出版社和书籍一对多 创建一对一的关系:OneToOne("要绑定关系的表 ...
- django基础之day05,F与Q查询,Q查询的高级用法
#F与Q查询 #*************************** F 查询 ******************** # F 查询数据库中的其他字段!!! #1.查询库存数大于卖出数的书籍 fr ...
- Django中manger/QuerySet类与mysql数据库的查询
Django中的单表操作 1.精确查询 #查询的结果返回是容器Query Set的函数(Query Set模型类)# 1. all() 查询的所有的符合条件的结果,支持正向索引,支持索引切片,不 ...
- django F与Q查询 事务 only与defer
F与Q 查询 class Product(models.Model): name = models.CharField(max_length=32) #都是类实例化出来的对象 price = mode ...
随机推荐
- [GO]接口的嵌用继承
package main import "fmt" type Humaner interface { SayHi() } type Personer interface { Hum ...
- ceph中pool的管理
1.创建pool 创建ceph pool的命令如下,它的参数包括pool名字.PG和PGP的数量. 若少于5个OSD, 设置pg_num为128. 5~10个OSD,设置pg_num为512. 10~ ...
- mysql数据库引擎MyISAM与InnoDB的区别浅说
mysql的存储引擎包括:MyISAM.InnoDB.BDB.MEMORY.MERGE.EXAMPLE.NDBCluster.ARCHIVE.CSV.BLACKHOLE.FEDERATED等,其中In ...
- 编写高质量代码改善C#程序的157个建议——建议121:为应用程序设定运行权限
建议121:为应用程序设定运行权限 在某些情况下,可能存在这样的需求:只有系统管理员才能访问某应用程序的若干功能.这个时候,可以结合.NET中提供的代码访问安全性(Code Access Securi ...
- Android-Handler+Message-消息机制
我的理解是,子线程要和主线程通讯,就需要Handler+Message-消息机制 案例一:倒计时Demo(子线程+Handler+Message) package liudeli.async; imp ...
- oracle数据库中修改已存在数据的字段
在oracle中,如果已经存在的数据的某些列,假如要更换类型的话,有的时候是比较麻烦的, 会出现:ORA-01439: column to be modified must be empty to c ...
- duilib入门简明教程 -- XML配置界面(6)
前面那些教程都是为了让小伙伴们从win32.MFC过渡到duilib,让大家觉得duilib不是那么陌生,如果大家现在还对duilib非常陌生的话,那就说明前面的教程做得不好,请大家在下面留言, ...
- django+echarts
思路: 统一返回数据类型为json,然后前端发起Ajax请求后台数据接口 views.py def count_blog(request): # 下面等价于:select distinct auth, ...
- python版本selenium定位方式(不止八种哦)
除了大家熟知的8种定位方式之外 1.id定位:find_element_by_id(self, id_)2.name定位:find_element_by_name(self, name)3.class ...
- MSSQL Server中partition by与group by的区别
在使用over等开窗函数时,over里头的分组及排序的执行晚于“where,group by,order by(但此排序顺序优先级是最高的)”的执行. ①group by 列名 合并(列值相同的并作一 ...