67、django之模型层(model)--查询补充及cookie
已经连续写了好几篇django的模型层(model)增删改查的随笔了,没篇大篇幅都是查询相关的操作,可以看出查询在数据的操作中是多么的重要,而本篇最后再补充一点关于关于查询的一些方法,模型层基本的操作也就结束了。然后会有一部分cookie的知识点,你可以为上篇随笔的图书管理小练习加上简单的登录。一个当然所有的讲解都是django一些浅显的知识,希望可以对读者有所帮助。
本篇导航:
1、以Book表为例
class Book(models.Model) :
title = models.CharField(max_length=32)
publish = models.DateField()
price = models.DecimalField(max_digits=5,decimal_places=2)
commnetNum = models.IntegerField()
keepNum = models.IntegerField()
2、F 查询
在之前所有的例子中,我们查询条件都只是将字段值与某个常量做比较。如果我们要对两个字段的值做比较,用以前的语法是无法实现的会飘红想要实现字段与字段相比较就只有用一个新的语法 F 查询(使用前需要使用import导入F)
1)字段比较
# 查询评论数大于收藏数的书籍
from django.db.models import F
Book.objects.filter(commnetNum__lt=F('keepNum'))
2)Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。
# 查询评论数大于收藏数2倍的书籍
Book.objects.filter(commnetNum__lt=F('keepNum')*2)
3)修改操作也可以使用F函数
#将每一本书的价格提高30元
Book.objects.all().update(price=F("price")+30)
3、Q 查询
如果有多条查询条件我们想要实现 ‘与’ 的效果只需要用逗号将每个条件隔开就好,那么怎么实现 ‘或’ ‘非’ 呢 这就用到Q语句了(使用前需要使用import导入Q)
Q 对象可以使用& 和| 操作符组合起来。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询
#书名是西游或水浒 |
Book.objects.filter(Q(title="西游")|Q(title="水浒"))
#作者是布吉岛或者不是2017年出版的书籍 & ~
#这个例子涉及多表关联可以用上篇随笔中的表结构
bookList=Book.objects.filter(Q(authorlish__name="布吉岛") & ~Q(publishDate__year=2017)).values_list("title")
1、cookie简述
1)cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生。
2)cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“谁”了。
3)cookie虽然在一定程度上解决了“保持状态”的需求,但是由于cookie本身最大支持4096字节,以及cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是session。(下篇随笔介绍session)
4)我们可以给每个客户端的cookie分配一个唯一的id,这样用户在访问时,通过cookie,服务器就知道来的人是“谁”。然后我们再根据不同的cookie的id,在服务器上保存一段时间的私密资料,如“账号密码”等等。
cookie弥补了http无状态的不足,让服务器知道来的人是“谁”;但是cookie以文本的形式保存在本地,自身安全性较差;所以我们就通过cookie识别不同的用户,对应的在session里保存私密的信息以及超过4096字节的文本。
2、简单实现登录效果
1)cookie的获取
request.COOKIES['key']
或
request.COOKIES.get('key')
2)cookie的设置
rep = HttpResponse(...) 或 rep = render(request, ...) 或 rep = redirect()
rep.set_cookie()
3)参数
''' def set_cookie(self, key, 键 value='', 值 max_age=None, 超长时间 expires=None, 超长时间 path='/', Cookie生效的路径, 浏览器只会把cookie回传给带有该路径的页面,这样可以避免将 cookie传给站点中的其他的应用。 / 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问 domain=None, Cookie生效的域名 你可用这个参数来构造一个跨站cookie。 如, domain=".example.com" 所构造的cookie对下面这些站点都是可读的: www.example.com 、 www2.example.com 和an.other.sub.domain.example.com 。 如果该参数设置为 None ,cookie只能由设置它的站点读取。 secure=False, 如果设置为 True ,浏览器将通过HTTPS来回传cookie。 httponly=False 只能http协议传输,无法被JavaScript获取 (不是绝对,底层抓包可以获取到也可以被覆盖) ): pass '''
4)实例
主页和登录页面 cookie可以保存20秒
def login(requset): if requset.method=="POST": username=requset.POST.get("user") password=requset.POST.get("pwd") ret=models.UserInfo.objects.filter(username=username,password=password) if ret: obj=redirect("/home/") obj.set_cookie("is_login",True,20) obj.set_cookie("username",username) return obj else: return redirect("/login/") return render(requset,"login.html") def index(request): is_login=request.COOKIES.get("is_login",None) if is_login: username=request.COOKIES.get("username") return render(request, "index.html",locals()) else: return redirect("/login/")
3、删除cookie
response.delete_cookie()
4、cookie存储到客户端
优点:数据存在在客户端,减轻服务器端的压力,提高网站的性能。
缺点:安全性不高:在客户端机很容易被查看或破解用户会话信息