Django笔记
Django笔记 3、WEB框架 MVC Model View Controller 数据库 模板文件 业务处理 MTV Model Template View 数据库 模板文件 业务处理 ############## WEB:MVC、MTV 4、Django 1、框架的安装:pip3 install django C:\Python35\Scripts # 创建Django工程,首先cd到项目根目录,命令行下执行 2、创建应用:django-admin startproject 【工程名称】 mysite - mysite # 对整个程序进行配置 - init - settings # 配置文件:含模板、静态文件等路径配置 - url # URL对应关系 - wsgi # 遵循WSIG规范,uwsgi + nginx - manage.py # 管理Django程序: - python manage.py - python manage.py startapp xx - python manage.py makemigrations - python manage.py migrate # 运行Django功能 python manage.py runserver 127.0.0.1:8001 chouti - chouti - 配置 - 主站 app - 后台管理 app # 创建app python manage.py startapp cmdb python manage.py startapp openstack python manage.py startapp xxoo.... app: migrations 数据修改表结构 admin Django为我们提供的后台管理 apps 配置当前app models ORM,写指定的类 通过命令可以创建数据库结构 tests 单元测试 views 业务代码 settings配置 1、配置模板的路径 TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] 2、配置静态目录 static STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), ) <link rel="stylesheet" href="/static/commons.css" /> 内容整理 1. 创建Django工程 django-admin startproject 工程名 2. 创建APP cd 工程名 python manage.py startapp cmdb 3、静态文件 project.settings.py STATICFILES_DIRS = ( os.path.join(BASE_DIR, "static"), ) 4、模板路径 DIRS ==> [os.path.join(BASE_DIR,'templates'),] 5、settings中 middlerware # 注释 csrf 6、定义路由规则 url.py "login" --> 函数名 url('upload', views.upload),是一种 url('home', views.Home.as_view()), 是一种方式 url('home', views.Home.as_view()), 是一种方式 7、定义视图函数 app下views.py def func(request): # request.method GET / POST # http://127.0.0.1:8009/home?nid=123&name=alex # request.GET.get('',None) # 获取请求发来的而数据 # request.POST.get('',None) # return HttpResponse("字符串") # return render(request, "HTML模板的路径") # return redirect('/只能填URL') #面向对象写法进行方法定义。 class Home(View): def dispatch(self, request, *args, **kwargs): print('before') result = super(Home,self).dispatch(request,*args,**kwargs) print('after') return result def get(self,request): print(request.method) return render(request,'upload.html') def post(self,request): print(request.method) return redirect('/home') 8、模板渲染 特殊的模板语言 -- {{ 变量名 }} def func(request): return render(request, "index.html", {'current_user': "alex"}) index.html <html> .. <body> <div>{{current_user}}</div> </body> </html> ====> 最后生成的字符串 <html> .. <body> <div>alex</div> </body> </html> -- For循环 def func(request): return render(request, "index.html", {'current_user': "alex", 'user_list': ['alex','eric']}) index.html <html> .. <body> <div>{{current_user}}</div> <ul> {% for row in user_list %} {% if row == "alex" %} <li>{{ row }}</li> {% endif %} {% endfor %} </ul> </body> </html> #####索引################# def func(request): return render(request, "index.html", { 'current_user': "alex", 'user_list': ['alex','eric'], 'user_dict': {'k1': 'v1', 'k2': 'v2'}}) index.html <html> .. <body> <div>{{current_user}}</div> <a> {{ user_list.1 }} </a> <a> {{ user_dict.k1 }} </a> <a> {{ user_dict.k2 }} </a> </body> </html> ###### 条件 def func(request): return render(request, "index.html", { 'current_user': "alex", "age": 18, 'user_list': ['alex','eric'], 'user_dict': {'k1': 'v1', 'k2': 'v2'}}) index.html <html> .. <body> <div>{{current_user}}</div> <a> {{ user_list.1 }} </a> <a> {{ user_dict.k1 }} </a> <a> {{ user_dict.k2 }} </a> {% if age %} <a>有年龄</a> {% if age > 16 %} <a>老男人</a> {% else %} <a>小鲜肉</a> {% endif %} {% else %} <a>无年龄</a> {% endif %} </body> </html> XXOO管理: MySQL SQLAlchemy 主机管理(8列): IP 端口 业务线 ... 用户表: 用户名 密码 功能: 1、 登录 2、主机管理页面 - 查看所有的主机信息(4列) - 增加主机信息(8列) ** 模态对话框 3、查看详细 url: "detail" -> detail def detail(reqeust): nid = request.GET.get("nid") v = select * from tb where id = nid ... 4、删除 del_host -> delete_host def delete_host(request): nid = request.POST.get('nid') delete from tb where id = nid return redirect('/home') 上节内容回顾: 1、Django请求生命周期 -> URL对应关系(匹配) -> 视图函数 -> 返回用户字符串 -> URL对应关系(匹配) -> 视图函数 -> 打开一个HTML文件,读取内容 2、创建django projcet django-admin startproject mysite .. mysite mysite - 配置文件 - url.py - settings.py cd mysite python manage.py startapp cmdb mysite mysite - 配置文件 - url.py - settings.py cmdb - views.py - admin.py - models.py # 创建数据库表 3、配置 模板路径 静态文件路径 # CSRF 4、编写程序 a. url.py /index/ -> func b. views.py def func(request): # 包含所有的请求数据 ... return HttpResponse('字符串') return render(request, 'index.html', {''}) retrun redirect('URL') c. 模板语言 return render(request, 'index.html', {'li': [11,22,33]}) {% for item in li %} <h1>{{item}}</h1> {% endfor %} *********** 索引用点 ********** <h2> {{item.0 }} </h2> 一、路由系统,URL 1、url(r'^index/', views.index), url(r'^home/', views.Home.as_view()), 2、url(r'^detail-(\d+).html', views.detail), 3、url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail) PS: def detail(request, *args,**kwargs): pass 实战: a. url(r'^detail-(\d+)-(\d+).html', views.detail), def func(request, nid, uid): pass def func(request, *args): args = (2,9) def func(request, *args, **kwargs): args = (2,9) b. url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail) def func(request, nid, uid): pass def funct(request, **kwargs): kwargs = {'nid': 1, 'uid': 3} def func(request, *args, **kwargs): args = (2,9) 4、 name 对URL路由关系进行命名, ***** 以后可以根据此名称生成自己想要的URL ***** url(r'^asdfasdfasdf/', views.index, name='i1'), url(r'^yug/(\d+)/(\d+)/', views.index, name='i2'), url(r'^buy/(?P<pid>\d+)/(?P<nid>\d+)/', views.index, name='i3'), def func(request, *args, **kwargs): from django.urls import reverse url1 = reverse('i1') # asdfasdfasdf/ url2 = reverse('i2', args=(1,2,)) # yug/1/2/ url3 = reverse('i3', kwargs={'pid': 1, "nid": 9}) # buy/1/9/ xxx.html {% url "i1" %} # asdfasdfasdf/ {% url "i2" 1 2 %} # yug/1/2/ {% url "i3" pid=1 nid=9 %} # buy/1/9/ 注: # 当前的URL request.path_info 5、多级路由 project/urls.py from django.conf.urls import url,include from django.contrib import admin urlpatterns = [ url(r'^cmdb/', include("app01.urls")), url(r'^monitor/', include("app02.urls")), ] app01/urls.py from django.conf.urls import url,include from django.contrib import admin from app01 import views urlpatterns = [ url(r'^login/', views.login), ] app02/urls.py from django.conf.urls import url,include from django.contrib import admin from app02 import views urlpatterns = [ url(r'^login/', views.login), ] 6、默认值(欠) 7、命名空间(欠) 二、视图 1、获取用户请求数据 request.GET request.POST request.FILES PS: GET:获取数据 POST:提交数据 2、checkbox等多选的内容 request.POST.getlist() 3、上传文件 # 上传文件,form标签做特殊设置 obj = request.FILES.get('fafafa') obj.name f = open(obj.name, mode='wb') for item in obj.chunks(): f.write(item) f.close() 4、FBV & CBV function base view url.py index -> 函数名 view.py def 函数(request): ... ====》 /index/ -> 函数名 /index/ -> 类 ====》 建议:两者都用 5、装饰器 欠 三、模板 四、ORM操作 select * from tb where id > 1 # 对应关系 models.tb.objects.filter(id__gt=1) models.tb.objects.filter(id=1) models.tb.objects.filter(id__lt=1) 创建类 a. 先写类 from django.db import models # app01_userinfo class UserInfo(models.Model): # id列,自增,主键 # 用户名列,字符串类型,指定长度 username = models.CharField(max_length=32) password = models.CharField(max_length=64) b. 注册APP INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01', ] c. 执行命令 python manage.py makemigrations python manage.py migrate d. ********** 注意 *********** Django默认使用MySQLdb模块链接MySQL 主动修改为pymysql,在project同名文件夹下的__init__文件中添加如下代码即可: import pymysql pymysql.install_as_MySQLdb() 1. 根据类自动创建数据库表 # app下的models.py python manage.py makemigrations python manage.py migrate 字段: 字符串类型 数字 时间: #创建时间ctime(数据最初创建的时间) ctime = models.DateTimeField(auto_now_add=True,null=True) #数据更新时间,数据更新时uptime字段的的值也自动随当前时间更新:触发有条件:必须为filter过滤出来的数据对象。 uptime = models.DateTimeField(auto_now=True,null=True) 二进制 自增(primary_key=True) 字段的参数: null -> db是否可以为空 default -> 默认值 primary_key -> 主键 db_column -> 列名 db_index -> 索引 unique -> 唯一索引 unique_for_date -> unique_for_month unique_for_year auto_now -> 创建时,自动生成时间 auto_now_add -> 更新时,自动更新为当前时间 # obj = UserGroup.objects.filter(id=1).update(caption='CEO') # obj = UserGroup.objects.filter(id=1).first() # obj.caption = "CEO" # obj.save() choices -> django admin中显示下拉框,避免连表查询 blank -> django admin是否可以为空 verbose_name -> django admin显示字段中文 editable -> django admin是否可以被编辑,字段写上这个=False,admin管理时不显示该列 error_messages -> 错误信息欠 help_text -> django admin提示 validators -> django form ,自定义错误信息(欠) #admin管理项目 创建 Django 用户:python manage.py createsuperuser app01/admin.py 添加: from app01 import models admin.site.register(models.UserInfo) admin.site.register(models.UserGroup) 2. 根据类对数据库表中的数据进行各种操作 一对多: a. 外键 b. 外键字段_id c. models.tb.object.create(name='root', user_group_id=1) d. userlist = models.tb.object.all() for row in userlist: row.id row.user_group_id row.user_group.caption on_delete=None, # 删除关联表中的数据时,当前表与其关联的field的行为 on_delete=models.CASCADE, # 删除关联数据,与之关联也删除 on_delete=models.DO_NOTHING, # 删除关联数据,什么也不做 on_delete=models.PROTECT, # 删除关联数据,引发错误ProtectedError # models.ForeignKey('关联表', on_delete=models.SET_NULL, blank=True, null=True) on_delete=models.SET_NULL, # 删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空,一对一同理) # models.ForeignKey('关联表', on_delete=models.SET_DEFAULT, default='默认值') on_delete=models.SET_DEFAULT, # 删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值,一对一同理) on_delete=models.SET, # 删除关联数据, a. 与之关联的值设置为指定值,设置:models.SET(值) b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象) --------------------- 作者:buxianghejiu 来源:CSDN 原文:https://blog.csdn.net/buxianghejiu/article/details/79086011 版权声明:本文为博主原创文章,转载请附上博文链接! =================== 作业:用户管理 ==================== 1、用户组的增删改查 2、用户增删该查 - 添加必须是对话框 - 删除必须是对话框 - 修改,必须显示默认值 3、比较好看的页面 4、预习: http://www.cnblogs.com/wupeiqi/articles/5246483.html 1、Django请求的生命周期 武彦涛: 路由系统 -> 试图函数(获取模板+数据=》渲染) -> 字符串返回给用户 2、路由系统 王腾: /index/ -> 函数或类.as_view() /detail/(\d+) -> 函数(参数) 或 类.as_view()(参数) /detail/(?P<nid>\d+) -> 函数(参数) 或 类.as_view()(参数) /detail/ -> include("app01.urls") /detail/ name='a1' -> include("app01.urls") - 视图中:reverse - 模板中:{% url "a1" %} 3、视图 陈一波: FBV:函数 def index(request,*args,**kwargs): .. CBV:类 class Home(views.View): def get(self,reqeust,*args,**kwargs): .. 获取用户请求中的数据: request.POST.get request.GET.get reqeust.FILES.get() # checkbox, ........getlist() request.path_info 文件对象 = reqeust.FILES.get() 文件对象.name 文件对象.size 文件对象.chunks() # <form 特殊的设置></form> 给用户返回数据: render(request, "模板的文件的路径", {'k1': [1,2,3,4],"k2": {'name': '张扬','age': 73}}) redirect("URL") HttpResponse(字符串) 4、模板语言 冯国富: 肾阳 程表 高晓峰 render(request, "模板的文件的路径", {'obj': 1234, 'k1': [1,2,3,4],"k2": {'name': '张扬','age': 73}}) <html> <body> <h1> {{ obj }} </h1> <h1> {{ k1.3 }} </h1> <h1> {{ k2.name }} </h1> {% for i in k1 %} <p> {{ i }} </p> {% endfor %} {% for row in k2.keys %} {{ row }} {% endfor %} {% for row in k2.values %} {{ row }} {% endfor %} {% for k,v in k2.items %} {{ k }} - {{v}} {% endfor %} {{ forloop.parentloop }} 父类for循环的关系 {{ forloop.count }} 循环计数器 </body> </html> 5、ORM 吴世鹏 闫利鹏 a. 创建类和字段 class User(models.Model): age = models.IntergerFiled() name = models.CharField(max_length=10)#字符长度 Python manage.py makemigrations python manage.py migrate # settings.py 注册APP b. 操作 王赛鹏 增 models.User.objects.create(name='qianxiaohu',age=18) dic = {'name': 'xx', 'age': 19} models.User.objects.create(**dic) obj = models.User(name='qianxiaohu',age=18) obj.save() 删 models.User.objects.filter(id=1).delete() 改 models.User.objects.filter(id__gt=1).update(name='alex',age=84) dic = {'name': 'xx', 'age': 19} models.User.objects.filter(id__gt=1).update(**dic) 查 models.User.objects.filter(id=1,name='root') models.User.objects.filter(id__gt=1,name='root') models.User.objects.filter(id__lt=1) models.User.objects.filter(id__gte=1) models.User.objects.filter(id__lte=1) models.User.objects.filter(id=1,name='root') dic = {'name': 'xx', 'age__gt': 19} models.User.objects.filter(**dic) v1 = models.Business.objects.all() # QuerySet ,内部元素都是对象 # QuerySet ,内部元素都是字典 v2 = models.Business.objects.all().values('id','caption') # QuerySet ,内部元素都是元组 v3 = models.Business.objects.all().values_list('id','caption') # 获取到的一个对象,如果不存在就报错 models.Business.objects.get(id=1) 对象或者None = models.Business.objects.filter(id=1).first() 外键: v = models.Host.objects.filter(nid__gt=0) v[0].b.caption ----> 通过.进行跨表 外键: class UserType(models.Model): caption = models.CharField(max_length=32) id caption # 1,普通用户 # 2,VIP用户 # 3, 游客 class User(models.Model): age = models.IntergerFiled() name = models.CharField(max_length=10)#字符长度 # user_type_id = models.IntergerFiled() # 约束, user_type = models.ForeignKey("UserType",to_field='id') # 约束, name age user_type_id # 张扬 18 3 # 张A扬 18 2 # 张B扬 18 2 张扬: position:fixed absolute relative Ajax $.ajax({ url: '/host', type: "POST", data: {'k1': 123,'k2': "root"}, success: function(data){ // data是服务器端返回的字符串 var obj = JSON.parse(data); } }) 建议:永远让服务器端返回一个字典 return HttpResponse(json.dumps(字典)) 多对多: 创建多对多: 方式一:自定义关系表 class Host(models.Model): nid = models.AutoField(primary_key=True) hostname = models.CharField(max_length=32,db_index=True) ip = models.GenericIPAddressField(protocol="ipv4",db_index=True) port = models.IntegerField() b = models.ForeignKey(to="Business", to_field='id') # 10 class Application(models.Model): name = models.CharField(max_length=32) # 2 class HostToApp(models.Model): hobj = models.ForeignKey(to='Host',to_field='nid') aobj = models.ForeignKey(to='Application',to_field='id') # HostToApp.objects.create(hobj_id=1,aobj_id=2) 方式二:自动创建关系表 class Host(models.Model): nid = models.AutoField(primary_key=True) hostname = models.CharField(max_length=32,db_index=True) ip = models.GenericIPAddressField(protocol="ipv4",db_index=True) port = models.IntegerField() b = models.ForeignKey(to="Business", to_field='id') #db_index=True 表示创建索引 # 10 class Application(models.Model): name = models.CharField(max_length=32) r = models.ManyToManyField("Host") #第三张表只有三列(id,application_id,host_id) 表名字为application_id 无法直接对第三张表进行操作,需要通过第二张表的某条数据对象.第三张表名.操作 obj = Application.objects.get(id=1) 获取某条数据 obj.name # 第三张表操作 obj.r.add(1) 添加第三张表对应关系 Application_id=1 host_id=1 obj.r.add(2) 添加第三张表对应关系 Application_id=1 host_id=2 obj.r.add(2,3,4) 添加第三张表对应关系 Application_id=1 host_id=2; Application_id=1 host_id=3;..... obj.r.add(*[1,2,3,4]) 同上 obj.r.remove(1) obj.r.remove(2,4) obj.r.remove(*[1,2,3]) obj.r.clear() 清除Application.objects.get(id=1)的第三张表里面的所有对应数据 obj.r.set([3,5,7]) 清除Application.objects.get(id=1)的第三张表里面的所有对应数据,然后重新设置 # 所有相关的主机对象“列表” QuerySet obj.r.all() s14day21 上节内容回顾: 1、请求周期 url> 路由 > 函数或类 > 返回字符串或者模板语言? Form表单提交: 提交 -> url > 函数或类中的方法 - .... HttpResponse('....') render(request,'index.html') redirect('/index/') 用户 < < 返回字符串 (当接受到redirect时)自动发起另外一个请求 --> url ..... Ajax: $.ajax({ url: '/index/', data: {'k': 'v', 'list': [1,2,3,4], 'k3': JSON.stringfy({'k1': 'v'}))}, $(form对象).serialize() type: 'POST', dataType: 'JSON': traditional: true, //传输数组必备条件 success:function(d){ location.reload() # 刷新 location.href = "某个地址" # 跳转 } }) 提交 -> url -> 函数或类中的方法 HttpResponse('{}') render(request, 'index.html', {'name': 'v1'}) <h1>{{ name }}</h1> --> <h1>v1</h1> XXXXXXX redirect... 用户 <<<<< 字符串 2、路由系统URL a. /index/ -> 函数或类 b. /index/(\d+) -> 函数或类 c. /index/(?P<nid>\d+) -> 函数或类 d. /index/(?P<nid>\d+) name='root' -> 函数或类 reverse() {% url 'root' 1%} e. /crm/ include('app01.urls') -> 路由分发 f. 默认值 url(r'^index/', views.index, {'name': 'root'}), def index(request,name): print(name) return HttpResponse('OK') g. 命名空间 /admin/ include('app01.urls',namespace='m1') /crm/ include('app01.urls',namespace='m1') app01.urls /index/ name = 'n1' reverser('m1:n1') 3、 def func(request): request.POST request.GET request.FILES request.getlist request.method request.path_info return render,HttpResponse,redirect 4、 render(request, 'index.html') # for # if # 索引. keys values items all 5、 class User(models.Model): username = models.CharField(max_length=32) email = models.EmailField() 有验证功能 Django Admin 无验证功能: User.objects.create(username='root',email='asdfasdfasdfasdf') User.objects.filter(id=1).update(email='666') class UserType(models.Model): name = models.CharField(max_length=32) class User(models.Model): username = models.CharField(max_length=32) email = models.EmailField() user_type = models.ForeignKey("UserType") user_list = User.objects.all() for obj user_list: obj.username,obj.email,obj.user_type_id,obj.user_type.name,obj.user_type.id user = User.objects.get(id=1) user. User.objects.all().values("username","user_type__name",) class UserType(models.Model): name = models.CharField(max_length=32) class User(models.Model): username = models.CharField(max_length=32) email = models.EmailField() user_type = models.ForeignKey("UserType") m = models.ManyToMany('UserGroup') class UserGroup(models.Model): name = .... obj = User.objects.get(id=1) obj.m.add(2) obj.m.add(2,3) obj.m.add(*[1,2,3]) obj.m.remove(...) obj.m.clear() obj.m.set([1,2,3,4,5]) # 多个组,UserGroup对象 obj.m.all() obj.m.filter(name='CTO') 知识点: URL - 两个 Views - 请求的其他信息 from django.core.handlers.wsgi import WSGIRequest request.environ request.environ['HTTP_USER_AGENT'] - 装饰器 FBV: def auth(func): def inner(reqeust,*args,**kwargs): v = reqeust.COOKIES.get('username111') if not v: return redirect('/login/') return func(reqeust, *args,**kwargs) return inner CBV: from django import views from django.utils.decorators import method_decorator @method_decorator(auth,name='dispatch') class Order(views.View): # @method_decorator(auth) # def dispatch(self, request, *args, **kwargs): # return super(Order,self).dispatch(request, *args, **kwargs) # @method_decorator(auth) def get(self,reqeust): v = reqeust.COOKIES.get('username111') return render(reqeust,'index.html',{'current_user': v}) def post(self,reqeust): v = reqeust.COOKIES.get('username111') return render(reqeust,'index.html',{'current_user': v}) Templates - 母版...html extends include - 自定义函数 simple_tag a. app下创建templatetags目录 b. 任意xxoo.py文件 c. 创建template对象 register d. @register.simple_tag def func(a1,a2,a3....) return "asdfasd" e. settings中注册APP f. 顶部 {% load xxoo %} g. {% 函数名 arg1 arg2 %} 缺点: 不能作为if条件 优点: 参数任意 filter a. app下创建templatetags目录 b. 任意xxoo.py文件 c. 创建template对象 register d. @register.filter def func(a1,a2) return "asdfasd" e. settings中注册APP f. 顶部 {% load xxoo %} g. {{ 参数1|函数名:"参数二,参数三" }} {{ 参数1|函数名:数字 }} 缺点: 最多两个参数,不能加空格 优点: 能作为if条件 分页(自定义的分页) XSS: {{ page_str|safe }} mark_safe(page_str) cookie 客户端浏览器上的一个文件 {"user": 'dachengzi'} 获取cookie $.cookie('per_page_count', {'path': "/user_list/`"}); 设置cookie $.cookie('per_page_count',v, {'path': "/user_list/"}); session :装饰器 Models - 一大波操作 Form验证 - 缓存 中间件 信号 CSRF Admin/ModelForm 作业: 主机管理: 1、单表操作 2、一对多 3、多对多 要求: a. 删除对话框 b. 修改,添加新URL c. 基于cookie进行用户认证 d. 定制显示个数 e. 分页 预习: Form: http://www.cnblogs.com/wupeiqi/articles/6144178.html Model:http://www.cnblogs.com/wupeiqi/articles/6216618.html day22 知识点概要 - Session - CSRF - Model操作 - Form验证(ModelForm) - 中间件 - 缓存 - 信号 内容详细: 1. Session 基于Cookie做用户验证时:敏感信息不适合放在cookie中 a. Session原理 Cookie是保存在用户浏览器端的键值对 Session是保存在服务器端的键值对 b. Cookie和Session对比 c. Session配置(缺少cache) d. 示例:实现两周自动登陆 - request.session.set_expiry(60*10) - SESSION_SAVE_EVERY_REQUEST = True PS: cookie中不设置超时时间,则表示关闭浏览器自动清除 - session依赖于cookie - 服务器session request.session.get() request.session[x] = x request.session.clear() - 配置文件中设置默认操作(通用配置): 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过期(默认) # set_cookie('k',123) SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认) #每次请求更新session过期时间 SESSION_SAVE_EVERY_REQUEST = True 配置存放session的位置 a.使用数据库 SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认) b.使用缓存存放session SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 SESSION_CACHE_ALIAS = 'default' c.使用缓存+数据库 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' d.使用文件 SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎 SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T 使用 def index(request): # 获取、设置、删除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的随机字符串 request.session.session_key # 将所有Session失效日期小于当前日期的数据删除 request.session.clear_expired() # 检查 用户session的随机字符串 在数据库中是否 request.session.exists("session_key") # 删除当前用户的所有Session数据 request.session.delete("session_key") request.session.set_expiry(value) * 如果value是个整数,session会在些秒数后失效。 * 如果value是个datatime或timedelta,session就会在这个时间后失效。 * 如果value是0,用户关闭浏览器session就会失效。 * 如果value是None,session会依赖全局session失效策略。 - 引擎的配置 2. CSRF a. CSRF原理 b. 无CSRF时存在隐患 c. Form提交(CSRF) d. Ajax提交(CSRF) CSRF请求头 X-CSRFToken 设置方法: $.ajaxSetup({ beforeSend:function (xhr,settings) { xhr.setRequestHeader('X-CSRFtoken',$.cookie('csrftoken')); } }); 6. 中间件 CSRF全局设置:settings.py MIDDLEWARE = 'django.middleware.csrf.CsrfViewMiddleware', CSRF局部设置 from django.views.decorators.csrf import csrf_exempt,csrf_protect 设置个别函数不需要经过CSRF认证。【给函数加如下装饰器】 @csrf_exempt 设置个别函数需要经过CSRF认证。 【给函数加如下装饰器】 @csrf_protect ---自定义中间件: from django.utils.deprecation import MiddlewareMixin class 中间件名称(MiddlewareMixin): def process_request(self, request): 请求来的时候走这里 def process_response(self, request, response): 请求返回的的时候走这里,必须有return response return response def process_view(self,request,view_func,view_args,view_kwargs) def process_exception(self,reqeust,exception) Views 函数出错的时候异常处理用。 7. 缓存 Django中提供了6种缓存方式: 开发调试 内存 文件 数据库 Memcache缓存(python-memcached模块) Memcache缓存(pylibmc模块) 开发模式: # 此为开始调试用,实际内部不做任何操作 # 配置: CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # 引擎 'TIMEOUT': 300, # 缓存超时时间(默认300,None表示永不过期,0表示立即过期) 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大缓存个数(默认300) 'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) }, 'KEY_PREFIX': '', # 缓存key的前缀(默认空) 'VERSION': 1, # 缓存key的版本(默认1) 'KEY_FUNCTION' 函数名 # 生成key的函数(默认函数会生成为:【前缀:版本:key】) } } 内存模式: # 此缓存将内容保存至内存的变量中 # 配置: CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': 'unique-snowflake', } } # 注:其他配置同开发调试版本 文件模式: # 此缓存将内容保存至文件 # 配置: CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', 'LOCATION': '/var/tmp/django_cache', } } # 注:其他配置同开发调试版本 数据库模式: # 此缓存将内容保存至数据库 # 配置: CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', 'LOCATION': 'my_cache_table', # 数据库表 } } # 注:执行创建表命令 python manage.py createcachetable 缓存Mencache(python-memcached模块): # 此缓存使用python-memcached模块连接memcache CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': '127.0.0.1:11211', } } #socket方式 CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': 'unix:/tmp/memcached.sock', } } #集群 CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': [ '172.19.26.240:11211', '172.19.26.242:11211', ] } } Memcache缓存(pylibmc模块) CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', 'LOCATION': '127.0.0.1:11211', } } CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', 'LOCATION': '/tmp/memcached.sock', } } CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', 'LOCATION': [ '172.19.26.240:11211', '172.19.26.242:11211', ] } } Redis缓存(依赖:pip3 install django-redis) CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "CONNECTION_POOL_KWARGS": {"max_connections": 100} # "PASSWORD": "密码", } } } 缓存应用: 全站使用; 使用中间件,经过一系列的认证等操作,如果内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户,当返回给用户之前,判断缓存中是否已经存在,如果不存在则UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存 MIDDLEWARE = [ 'django.middleware.cache.UpdateCacheMiddleware', # 其他中间件... 'django.middleware.cache.FetchFromCacheMiddleware', ] CACHE_MIDDLEWARE_ALIAS = "" CACHE_MIDDLEWARE_SECONDS = "" CACHE_MIDDLEWARE_KEY_PREFIX = "" 单独视图缓存: 方式一: from django.views.decorators.cache import cache_page @cache_page(60 * 15) def my_view(request): ... 方式二: from django.views.decorators.cache import cache_page urlpatterns = [ url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)), ] 局部视图使用: a. 引入TemplateTag {% load cache %} b. 使用缓存 {% cache 5000 缓存key %} 缓存内容 {% endcache %} 复制代码 5种配置 3种应用: 全局 视图函数 模板 8. 信号 1、Django内置信号 Django中提供了“信号调度”,用于在框架执行操作时解耦。通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者。 Model signals pre_init # django的modal执行其构造方法前,自动触发 post_init # django的modal执行其构造方法后,自动触发 pre_save # django的modal对象保存前,自动触发 post_save # django的modal对象保存后,自动触发 pre_delete # django的modal对象删除前,自动触发 post_delete # django的modal对象删除后,自动触发 m2m_changed # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发 class_prepared # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发 Management signals pre_migrate # 执行migrate命令前,自动触发 post_migrate # 执行migrate命令后,自动触发 Request/response signals request_started # 请求到来前,自动触发 request_finished # 请求结束后,自动触发 got_request_exception # 请求异常后,自动触发 Test signals setting_changed # 使用test测试修改配置文件时,自动触发 template_rendered # 使用test测试渲染模板时,自动触发 Database Wrappers connection_created # 创建数据库连接时,自动触发 -内置信号的使用: from django.core.signals import request_finished from django.core.signals import request_started from django.core.signals import got_request_exception from django.db.models.signals import class_prepared from django.db.models.signals import pre_init, post_init from django.db.models.signals import pre_save, post_save from django.db.models.signals import pre_delete, post_delete from django.db.models.signals import m2m_changed from django.db.models.signals import pre_migrate, post_migrate from django.test.signals import setting_changed from django.test.signals import template_rendered from django.db.backends.signals import connection_created def callback(sender, **kwargs): print("xxoo_callback") print(sender,kwargs) xxoo.connect(callback) # xxoo指上述导入的内容 - 自定义 - 定义信号 - 出发信号 - 信号中注册函数 3. Form表单验证 Model创建 a. 字段类型 + 参数 class MyForm(Form): user = fields.CharField( error_messages={'required':'用户名不能为空'}, max_length=12, widget=widgets.TextInput(attrs={'id':'i1','class':'c1'}) ) pwd = fields.CharField( min_length=8, max_length=32, widget=widgets.PasswordInput(render_value=True), ) gender = fields.ChoiceField( choices=[(1,'男'),(2,'女')], initial=2, widget=widgets.RadioSelect ) city = fields.CharField( widget=widgets.Select(choices=[(1,'上海'),(2,'北京'),(3,'广州')]), initial=2 ) citys = fields.CharField( widget=widgets.SelectMultiple(choices=((1,'上海'),(2,'北京'),(3,'广州'))), initial=1 ) b. 连表字段 + 参数 c. Meta d. SQL操作: - 基本增删改查 - 进阶操作 - 正反查询 - 其他操作 e. 验证(弱) 4. Form操作 完成: - 验证用户请求 - 生成HTML (保留上一次提交的数据) 自定义: - 类 - 字段(校验) - 插件(生成HTML) 初始化操作: ============= 作业:xxxoo管理 ============= 用户验证:session 新URL:Form验证 中间件:IP过滤 信号:记录操作 CSRF: a. Form验证用户请求 b. Form生成HTML c. Form字段详细(自定义字段,Model...) + 插件 d. 自定义验证(钩子以及__all__) e. 注册示例: 用户名、密码、邮箱、手机号(RegexValidator或RegexField)、性别、爱好、城市 f. 初始化值 5. ModelForm a. Model+Form功能集合 b. save c. save + save_m2m
posted on 2020-04-12 10:04 zhangmingda 阅读(207) 评论(0) 编辑 收藏 举报