今日内容总结
0.昨日内容回顾
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 昨日内容回顾: 2 1.choices字段 3 只要是能够罗列出来的有限个选项都可以使用choices字段来做参数 4 1.学历,工作经历,性别,工作状态,客户来源,婚嫁 5 gender_choices = ((1,'male'),(2,'female'),(3,'others')) 6 gender = models.IntegerField(choices=gender_choices) 7 # 当gender存的是gender_choices中罗列的数字 那么就会有对应关系 8 # 但是如果存的数字不存在,那么也不会报错 正常存储 只不过没了对应关系而已 9 10 2.user_obj.gender # 结果是数字 11 user_obj.get_gender_display() 拿到数字所对应的注释 12 13 2.django的MTV与MVC模型 14 M:models 15 T:templates 16 V:views 17 MVC 18 M:models 19 V:views 20 C:controller 控制器(urls) 21 django自称是MTV但是MTV本质也是MVC 22 23 3.Ajax 24 异步提交 局部刷新 25 26 基本语法结构: 27 $.ajax({ 28 url:'', # 默认不写就是当前路径(不写,后缀,全称) 29 type:'post', # 请求方式 30 data:{'name':'jason} # 数据默认格式是urlencoded(name=jason&pwd=123) 31 success:function(data){ 32 # data 就是后返回的异步提交的结果 通常都是一个字典 33 if (data.code == 1000){ 34 # 状态码是1000的情况下 需要走的逻辑 35 }elif(data.code == 2000){ 36 # 状态码是2000的情况下 需要走的逻辑 37 }else{ 38 # 其他情况 需要的操作 39 } 40 } 41 }) 42 通常情况下 后端针对ajax交互 都是采取字典的形式 43 44 4.contentType前后端传输数据的编码方式 45 1.urlencoded >>> name=jason&pwd=123&hobby=read 46 2.formdata >>> 传文件/也支持传普通键值(name=jason&pwd=123&hobby=read) 47 3.application/json >>> json格式数据 (form表单是无法发送json格式数据的) 48 49 详解: 50 1.form,ajax表单默认的是urlencoded 51 django 后端针对不同的编码格式是如何处理的> 52 只要是符合urlencoded编码格式 都会被后端自动获取并解析放到request.POST中 53 如果是符合formdata那么文件会被自动解析放到request.FILES中 54 如果是json格式,后端默认不解析 ,以二进制形式放在request.body 你可以自己手动处理即可 55 56 2.ajax发送json格式数据 57 """前后端传输数据 一定要确保数据与编码方式的一致性""" 58 $.ajax({ 59 url:'', # 默认不写就是当前路径 (不写,后缀,全称) 60 type:'post', # 请求方式 61 data:JSON.stringify({'name':'jason'}), 62 # 数据 数据默认的格式是urlencoded(name=jason$pwd=123) 63 contentType:'application/json', 64 success:function(data){ 65 # data就是后返回的异步提交的结果 通常是一个字典 66 if (data.code == 1000){ 67 # 状态码是1000的情况需要走的逻辑 68 }elif(data.code == 2000){ 69 # 状态码是2000的情况需要走的逻辑 70 }else{ 71 # 其他情况 需要的操作 72 } 73 } 74 }) 75 3.ajax 发送文件 76 1.利用内置对象FormData 77 既可以 传文件 也可以是 普通的键值对 78 2.获取input 标签存储的文件对象 79 先用jQuery找到该input 标签,然后转成原生的js对象 80 然后固定语法 .files[0] 81 $('input')[0].files[0] 82 3.发送ajax请求 83 有两个关键性参数需要你指定 84 processData:false # //告诉前端不要处理数据 85 contentType:false # 不适合任何编码 86 django后端 就会普通的键值解析到request.POST中文件解析到request.FILES 87 88 89 补充: 90 1.sweetalert 91 注意推导思路 92 删除弹框 93 作业:图书管理的系统的删除书籍功能 94 2.序列化组件 95 from django.core import serializers 96 3.自定义分页器 97 1.quertset支持切片取值 98 需要你掌握的就是推导思路 99 后端 100 book_list = models.Book.objects.all() 101 page_obj = Paganation(current_page=request.GET.get('page',1),all_count=book_list.count()) 102 page_query = book_list[page_obj.start:page_obj.end] 103 # 将page_query,page_obj传递到前端即可 104 105 前端: 106 确保你的HTML页面 引入了bootstrap文件 107 # for循环page_query 展示数据 108 # page_obj.page_html|safe生成分页器页码样式
今日内容
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 02 多对多三种创建方式.mp4 2 03 forms组件简介.mp4 3 04 forms组件校验功能.mp4 4 05 forms组件三种渲染方式.mp4 5 06 forms组件展示错误信息.mp4 6 07 forms组件钩子函数使用.mp4 7 08 forms补充知识点.mp4 8 09 forms组件源码分析.mp4 9 10 cookie与session简介.mp4 10 11 cookie操作.mp4 11 12 session操作.mp4
1.多对多三种创建方式
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 1.多对多创建方式: 2 1.全自动(推荐使用) 3 优势:不需要你手动创建第三张表 4 不足:由于第三张表不是你手动创建的 也就是说第三张表字段是固定,无法做扩展 5 class Book(models.Model): 6 title = models.CharField(max_length=32) 7 price = models.DecimalField(max_digits=8,decimal_places=2) 8 # digits 数字 decimal_places 小数位数 9 authors = models.ManyToManyFiled(to='Author') 10 11 class Author(models.Model): 12 name = models.CharField(max_length=32) 13 14 2.纯手动(了解即可) 15 自己创建第三张表 16 优势: 第三张表可以任意的扩展字段 17 不足:orm查询不方便 18 class Book(models.Model): 19 title = models.CharField(max_length=32) 20 price = models.DecimalField(max_digits=8,decimal_places=2) 21 class Author(models.Model): 22 name = models.CharField(max_length=32) 23 24 class Book2Author(models.Model): 25 book = models.ForeignKey(to='Book') 26 author = models.ForeignKey(to='Author) 27 create_time = models.DataField(auto_now_add=True) 28 29 3.半自动(推荐使用****) 30 优势:结合了全自动和纯手动的两个优点 31 class Book(models.Models): 32 title = models.CharField(max_length=32) 33 price = models.DecimalField(max_digits=8,decimal_places=2) 34 authors = models.ManyToManyFields=('book','author') 35 # through 告诉django orm 书籍表he作者表的多对多关系 通过Book2Author来记录的 36 # through_fields 告诉django orm记录关系时用过Book2Author 表中的book字段和author字段来记录的 37 38 """ 39 多对多字段的 add set remove clear 不支持 40 """ 41 class Author(models.Model): 42 name = models.CharField(max_length=32) 43 # books = models.ManyToManyField(to='Book',through='Book2Author',through_field=('author','book')) 44 45 class Book2Author(models.model): 46 book = models.Foreignkey(to='Book') 47 author = models.Foreignkey(to='Author') 48 create_time = models.DateField(auto_now_add=True)
2.form组件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 2.forms组件 2 自己手动实现一个注册功能 3 当用户的用户名包含 '金并瓦梅' 提示不符合社会主义核心价值观 4 当用户的密码短于3位 提示密码太短 不符合要求 5 6 1.思路分析 7 1.前端页面搭建 >>> 渲染页面 8 2.校验数据是否合法 >>> 校验数据 9 3.展示错误信息 >>> 展示信息 10 2.forms组件的基本用法 11 1.写一个继承了forms.Form的类 12 from django import forms 13 class LoginForm(forms.Form): 14 username = forms.CharField(max_length=8,min_length=3) # 用户名最长八位数 最短三位数 15 password = forms.CharField(max_length=8,min_length=5) # 密码最长八位 ,最短五位 16 email = forms.EmailField() # email 必须是邮箱格式 17 18 2.基本使用 (点击下角 Python console) 19 from app01 import views 20 1.校验功能: 21 将需要校验的数据 以字典的方式 传递给自定义的类 实例化产生对象 22 form_obj = views.LoginForm({'username':'jason','password':'123','email':'123'}) 23 2.如何查看数据是否合法 24 form_obj.is_valid() # 指定所有的数据都符合要求 才会是True 25 反之 false 26 3.如何查看错误 原因 27 form_obj.errors 28 { 29 'password': ['Ensure this value has at least 5 characters (it has 3).'], 30 'email': ['Enter a valid email address.'] 31 } 32 4.如何查看通过校验的数据 33 form_obj.cleaned_data 34 {'username':'jason'} 35 ps: 36 1.自定义类中所有的字段默认都必须要传值的 37 2.可以额外传入类中没有定义的字段名 forms组件 不会去校验 也就意味着 多传 一点关系也没有 38 form_obj = views.LoginForm({'username':'jason','password':'123456','email':'123@qq.com'}) 39 form_obj.is_valid() 40 True 41 42 form_obj = views.LoginForm({'username':'jason','password':'123456'}) 43 form_obj.is_valid() 44 False 45 46 form_obj = views.LoginForm({'username':'jason','password':'123456','email':'123@qq.com','hobby':'read'}) 47 form_obj.is_valid() 48 True 49 50 3.渲染页面 51 forms字段的三种渲染方式: 52 1.方法一 53 <p>第一种渲染页面的方式</p> 54 {{form_obj.as_p}} 55 {{form_obj.as_ul}} 56 {{form_obj.as_table}} 57 58 2.方法二 59 <p>第二种渲染页面的方式(可扩展性较高 书写麻烦)</p> 60 <p>{{form_obj.username.label}}{{form_obj.username}}</p> 61 <p>{{form_obj.password.label}}{{form_obj.password}}</p> 62 <p>{{form_obj.email.label}}{{form_obj.email}}</p> 63 3.方法三 64 {% for foo in form_obj %} 65 <p>{{foo.label}}{{foo}}</p> 66 {% endfor %} 67 68 ps: 69 1.forms组件在帮你渲染页面的时候 只会渲染获取用户输入的标签 提交按钮需要你手动添加 70 2.input框 的label注释 不指定的情况下 默认用类中字段的首字母大写 71 3.校验数据的时候可以前后端都校验 做一个双重校验, 72 但是前段的校验可有可无 而后端的校验则 必须要有 因为前端的校验可以通过爬虫直接避开 73 4.前端取消浏览器校验功能 74 form标签指定 novalidate属性即可 75 <form action="" method="post" novalidate></form> 76 77 4.forms组件展示错误信息 78 required=False 允许为空 79 前端: 80 {% for foo form_obj %} 81 <p>{{foo.label}}:{{foo}} 82 <span> {{foo.errors.0}}</span> 83 </p> 84 {% endfor %} 85 后端代码: 86 password = forms.CharField(max_length=8,min_length=5,label='密码',error_messages={ 87 'max_length':'密码最大八位', 88 'min_length':'密码最小五位', 89 'required':'密码不能为空', 90 },required=False,validators=[RegexValidator(r'^[0-9]+$',数字必须以159开头)]) # 密码最长八位最短五位 91 92 5..钩子函数 93 forms组件暴露给用户 可以自定义的校验规则 94 局部钩子 ,针对一个字段做额外校验 95 全局钩子,针对多个字段做额外校验 96 97 用法:在自定义的form类中书写方法即可 98 # 局部钩子(针对某一个字段做额外的校验) 99 例:检验用户名中 不能包含666 一旦包含 提示 100 def clean_username(self): 101 username = self.cleaned_data.get('username') 102 if '666' in username: 103 self.add_error('username','光喊666是不行的 你得自己上') 104 return username 105 # 全局钩子(针对多个字段做额外的校验) 106 例:校验用户两次密码是否一致 107 def clean(self): 108 password = self.cleaned_data.get('password') 109 confirm_password = self.cleaned_data.get('confirm_password') 110 if not password == confirm_password: 111 self.add_error('confirm_password','两次密码不一致') 112 return self.cleaned_data 113 6.forms组件及其他操作(***) 114 1.required 是否必填 115 2.label 注释信息 116 3.error_messages 报错信息 117 4.initial 默认值 118 5.widget 控制标签属性和样式 119 widget = widgets.PasswordInput() 120 控制标签属性 121 widget = widgets.PasswordInput(attrs={'class':'form-control c1 c2','username':'jason'}) 122 123 了解: 124 1.radio 单选radio框 125 gender = forms.ChoiceField( 126 choices=((1, "男"), (2, "女"), (3, "保密")), 127 label="性别", 128 initial=3, 129 widget=forms.widgets.RadioSelect() 130 ) 131 2.单选的select框 132 hobby = forms.ChoiceField( 133 choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), 134 label="爱好", 135 initial=3, 136 widget=forms.widgets.Select() 137 ) 138 3.多选的select框 139 hobby1 = forms.MultipleChoiceField( 140 choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), 141 label="爱好", 142 initial=[1, 3], 143 widget=forms.widgets.SelectMultiple() 144 ) 145 4.checkbox 单选 146 keep = forms.ChoiceField( 147 label="是否记住密码", 148 initial="checked", 149 widget=forms.widgets.CheckboxInput() 150 ) 151 5.checkbox 多选 152 hobby2 = forms.MultipleChoiceField( 153 choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), 154 label="爱好", 155 initial=[1, 3], 156 widget=forms.widgets.CheckboxSelectMultiple() 157 7.foems组件源码分析: 158 form_obj.is_valid() 159 form_obj.cleaned_data 160 form_obj.errors()
3.cookie和session
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 2.cookie 与 session 2 3 由于http协议 是无状态的,无法记录用户状态 所以导致cookie,session的产生 4 5 6 cookie 就是保存在客户端浏览器上的键值对 7 工作原理: 8 当你登录成功后,浏览器上会保存一些信息 9 下次再访问的时候 就会带着这些信息去访问 服务端 服务端 通过这些来判断识别出你的身份 10 11 cookie虽然是写在客户端浏览器上的 但是 是 服务端 设置的 12 浏览器可以选择不服从命令 禁止写cookie 13 14 15 session 就是保存在服务器上的键值对 16 session虽然是保存在服务器上的键值对 17 但是它是依赖于cookie 工作的 18 19 服务端返回给浏览器一个随机的字符串 20 浏览器以键值对的形式保存 21 sessionid:随机字符串 22 23 浏览器在访问服务端时 就会将随机字符串携带上 24 后端获取随机串与后端的记录作对比 25 随机字符串1:数据1 26 随机字符串2:数据2 27 28 29 1.如何操作cookie 30 django返回给客户端浏览器的都必须是HttpResponse对象 31 return HttpResponse() 32 return render() 33 return redirect() 34 35 obj1 = HttpResponse() 36 return obj1 37 obj2 = render() 38 return obj2 39 obj3 = redirect() 40 return obj3 41 42 2.cookie方法: 43 设置cookie利用的就是HttpResponse对象 44 obj1 = HttpResponse() 45 obj1.set_cookie('k1','v1') 46 47 # 获取cookie 48 request.COOKIE.get() 49 50 # 删除cookie 51 obj1.delete_cookie('k1') 52 53 # 设置超时时间 54 max_age=None,超时时间 55 expires=None,超时时间(IE requires expires, so set it if hasn't been already.) 56 57 登录功能 58 59 60 3.session方法 61 1.设置session 62 request.session['name'] = 'jason' 63 """ 64 上面这一句话发生了三件事 65 1.django内部自动生成一个随机字符串 66 2.将随机字符串和你要保存的数据 写入django_session表中(现在内存中生成一个缓存记录 等到经过中间件的时候才会执行) 67 3.将产生的随机字符串发送给浏览器 写入 cookie 68 sessionid:随机字符串 69 """ 70 2.获取session 71 request.session.get('name') 72 """ 73 上面 这句话一共发生了三件事 74 1.django内部会自动从请求 信息中获取到随机字符串 75 2.拿着随机字符串去django_session表中比对 76 3.一旦对应上了就将对应的数据解析出来 放到request.session中 77 """ 78 django session 默认的超时时间是14天 79 django_session表中的一条记录针对一个浏览器 80 81 3.删除当前会话中所有session数据 82 request.session.delete() # 删除的是浏览器的sessionid 信息 83 84 # 删除当前的会话数据并删除会话的cookie 85 request.session.flush() # 将浏览器和服务端全部删除 86 这用于确保前面的会话数据不可以再次被用户的浏览器访问 87 例如: 88 django.contrib.auth.logout() 函数中就会调用它 89 90 # 设置会话Session和Cookie的超时时间 91 # set_expiry 美国时间(8:00) 和 北京时间(16:00)差距 八小时 92 request.session.set_expiry(value) 93 * 如果value是个整数 session会在显秒数后失效 94 * 如果value是个datatime 或 timedelta,session就会在这个时间后失效 95 * 如果value是0 用户关闭浏览器session就会失效 96 * 如果value是None,session会依赖全局session失效策略 97 总结:你在后期可以将一些数据保存到session表中,保存的数据 可以在后端任意位置获取到
作业
作业
基于session完整登陆校验