一、ORM回顾
1. 内容回顾 1. Django中使用ORM连接MySQL的步骤: 1. 创建数据库 2. 告诉Django连接哪个数据库 在settings.py中设置数据库相关的链接信息 3. 告诉Django使用pymysql代替MySQLdb来连接数据库 在和setting.py同级的__init__.py中写上 import pynmysql pymysql.install_as_MySQLdb() 4. 在models.py中定义类 5. 执行两个命令 1. python manage.py makemigrations --> 将model.py中的变更记录 登记在小本本上,对应的是app/migrations/xxx.py 2. python manage.py migrate --> 将上一步得到的变更记录翻译成SQL语句去数据库执行 2. ORM一对一(OneToOneField): 1. 完全可以存在一张表里 2. 为什么要拆分呢? 当一张表里字段比较多, 并且当某一部分字段的查询需求比另外一些要高很多的时候 3. ORM查询练习: 详见今日代码:周末ORM作业.py 4. ORM 单表操作: 1. create 2. get 3. delete 4. 修改 1. update() --> 只更新指定字段 2. obj.属性 = 值 --> 所有字段都更新 obj.save() 5. ORM外键操作 1. 外键应该设置在哪一张表里 --> 通常放在多的那一边 2. 正向查 .属性 3. 反向查 表名_set.all() 6. 多对多字段 1. 多对多字段应该设置在哪一张表? 2. 多对多的方法 1. add 2. set 3. clear 4. remove 7. ORM进阶 1. 聚合和分组 aggregate annotate 2. F和Q 1. F:字段与字段之间作比较的时候用F/使用原来字段的值做更新的时候 2. Q: 对查询做并集操作时 3. 事务
1 import os 2 3 if __name__ == "__main__": 4 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_demo.settings") 5 6 import django 7 8 django.setup() 9 10 # ORM查询练习 11 from app01 import models 12 13 # 查询书名里老男孩的书 14 # ret = models.Book.objects.filter(title__contains='老男孩') 15 # print(ret) 16 17 # 查找出版日期是2017年的书 18 # ret = models.Book.objects.filter(publish_date__year=2017) 19 # print(ret) 20 21 # 查找出版日期是2017年的书名 22 # ret = models.Book.objects.filter(publish_date__year=2017).values("title") 23 # print(ret) 24 25 # 查找价格大于10元的书 26 # ret = models.Book.objects.filter(price__gt=10) 27 # print(ret) 28 29 # 查找价格大于10元的书名和价格 30 # ret = models.Book.objects.filter(price__gt=10).values_list("title", "price") 31 # print(ret) 32 33 # 查找memo字段是空的书 34 # ret = models.Book.objects.filter(memo__isnull=True) 35 # print(ret) 36 37 # 查找名字以沙河开头的出版社 38 # ret = models.Publisher.objects.filter(name__startswith="沙河") 39 # print(ret) 40 41 # 跨表查询 42 # 查找书名是“跟Alex送外卖”的书的出版社 43 # 1. 基于对象的查询 44 # book_obj = models.Book.objects.filter(title='跟Alex送外卖').first() 45 # book_obj.publisher # 和我这本书关联的出版社对象 46 # ret = book_obj.publisher.name 47 # print(ret) 48 # 2. 基于字段的查询 49 # ret = models.Publisher.objects.filter(book__title='跟Alex送外卖') 50 # print(ret) 51 52 # 查找书名是“跟老男孩学Linux”的书的所有作者 53 # 1. 基于对象的查询 54 # book_obj = models.Book.objects.filter(title='跟老男孩学Linux').first() 55 # ret = book_obj.author.all() # 反向查询是表名_set 56 # print(ret) 57 # 2. 基于字段的查询 58 # ret = models.Author.objects.filter(book__title='跟老男孩学Linux') 59 # print(ret) 60 61 # 查找书名是“跟老男孩学Linux”的书的作者的邮箱 62 # 1. 基于对象的查询 63 # book_obj = models.Book.objects.filter(title='跟老男孩学Linux').first() 64 # author_objs = book_obj.author.all() 65 # for author in author_objs: 66 # print(author.detail.email) 67 # 2. 基于字段的查询 68 # ret = models.Author.objects.filter(book__title='跟老男孩学Linux').values("detail__email") 69 # print(ret) 70 71 # update和直接属性修改的区别 72 # 1. update 73 # models.Book.objects.filter(id=1).update(price=999.99) 74 75 # 2. obj.price = 99.99 76 # book_obj = models.Book.objects.filter(id=1).first() 77 # book_obj.price = 99.99 78 # book_obj.save() 79 80 # 求所有书的平均价格 81 from django.db.models import Avg 82 # ret = models.Book.objects.all().aggregate(xx=Avg("price")) 83 # print(ret) 84 85 # 求每个作者出版的书的平均价格 86 # ret = models.Author.objects.annotate(xx=Avg("book__price")).values("name", "xx") 87 # print(ret) 88 89 # 查询出版日期是2017年或者价格小于100块的书 90 # from django.db.models import Q 91 # # ret = models.Book.objects.filter(publish_date__year=2017, price__lt=100) 92 # ret = models.Book.objects.filter(Q(publish_date__year=2017) | Q(price__lt=100)) 93 # print(ret) 94 95 # 事务 96 # from django.db import transaction 97 # 98 # try: 99 # with transaction.atomic(): 100 # # 先创建一个出版社 101 # publish_obj = models.Publisher.objects.create(name='腹疼出版社', city="沙河") 102 # # 把新创建的出版社和第一本书关联 103 # models.Book.objects.get(id=100).publisher = publish_obj 104 # except Exception as e: 105 # print(str(e)) 106 107 # 不使用事务方式 108 try: 109 # 先创建一个出版社 110 publish_obj = models.Publisher.objects.create(name='腹疼出版社', city="沙河") 111 # 把新创建的出版社和第一本书关联 112 models.Book.objects.get(id=100).publisher = publish_obj 113 except Exception as e: 114 print(str(e))
from functools import wraps def wrapper(func): @wraps(func) # 伏笔:Flask中会用到这个!!! def inner(*args, **kwargs): print("装饰器工作中...") func(*args, **kwargs) return inner @wrapper def f1(arg): """ 这是一个测试装饰器修复技术的函数 :param arg: 随便传 :return: 没有 """ print(arg) f1('呵呵') print(f1.__doc__)
二、cookie session
0. 登录的例子 无法判断用户是否登陆!! 1. Cookie 1. Cookie是什么? 就是保存在浏览器上的特殊的键值对 2. Cookie的特点 1. 服务端返回响应的时候 告诉浏览器要保存的键值对,浏览器可以设置不让服务端记录cookie 2. 浏览器每次访问同一个网站的时候会携带着当前这个网站保存在浏览器端的键值对 3. Cookie能做什么? 1. 做登录 ***** 2. 记录用户的浏览习惯 3. 简单的访问限制 4. Cookie其它配置项 1. 超时时间: max_age = 5 单位是秒;不设置超时时间的话默认是关闭浏览器就失效 2. 加密的Cookie 5. 需要掌握的是: django操作Cookie的方法
1)获取cookie
request.COOKIES['key']
request.get_signed_cookie(key,default=RAISE_ERROR,salt='',max_age=None)
2)设置cookie
rep = 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协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
----------------------------------------------------------------------------------------
3)删除cookie
rep.delete_cookie("user") # 删除用户浏览器上之前设置的usercookie 2. Session 1. 接收请求返回响应 2. 返回响应时,生成一个特殊的字符串 3. 在后端开一块空间保存你这个请求的相关数据 4. 返回响应 下一次请求: 1. 你带着 我之前给你的字符串 2. 拿着你的字符串去找你对应的箱子 3. 在箱子中根据key取值
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失效策略。
三、预习和扩展
1.回顾
from django.utils.decorators import method_decorator # 不会将get post等对象方法的self传入装饰器的*args等中
@wraper修饰的区别 直接装饰的会