111

Posted bigbox

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了111相关的知识,希望对你有一定的参考价值。

本周安排
	bbs全部结束

今日内容
	forms组件
	
	cookie与session操作

每日内容
	django中间件
	
	
	csrf跨站请求伪造
	
	
	auth认证模块
	
	bbs表设计
	
周三四五
	bbs业务实现

2020年目标
	坚持做一年
	今年目标确立

2019年         难 =  又  + 佳


上周内容回顾
	多对多三种创建方式
		1.纯自动
			第三张不需要你自己创建 由orm自动创建
			class Book(models):
				title = ...
				authors = models.ManyToManyField(to=‘Author‘)
			class Author(models):
				name = ...
			# 第三表扩展性较差
		2.纯手动
			class Book(models.Model):
				title = ...
				
			class Author(models.Model):
				name = ...
			
			class Book2Author(modes.Model):
				book = 一对多关系Book
				authors = 一对多关系Author
			# orm查询那一块 没有正反向的概念
		3.半自动
			class Book(models.Model):
				title = ...
				authors = models.ManyToManyField(to=‘Author‘,through=‘Book2Author‘,through_fields=(‘book‘,‘authors‘))
				
			class Author(models.Model):
				name = ...
				# books = models.ManyToManyField(to=‘Book‘,through=‘Book2Author‘,through_fields=(‘authors‘,‘book‘))
				
			class Book2Author(modes.Model):
				book = 一对多关系Book
				authors = 一对多关系Author
			# 不支持add、remove、set、clear
			
		# 完全靠业务逻辑来将表关系绑定起来

	ajax
		异步提交、局部刷新
			eg:github的注册页面
		
		基于jQuery封装之后的版本
			
		
		ajax基本语法结构
			$.ajax({
				url:‘‘,  # 控制的是数据的提交路径
				type:‘get/post‘,  # 控制的是数据的提交方式
				data:{‘usernamae‘:‘jason‘},  # 提交的数据
				success:function(data){  # 一旦异步提交有结果了 自动触发该函数的运行 形参data就是用来接收结果的
					...
				}
			
			})
			
	
	前后端传输数据编码格式
		urlencoded
			数据格式 username=jason&password=123
			是form表单和ajax默认的编码格式
			django后端针对符合该格式的数据都会自动解析并放到request.POST中
		formdata
			即可以发送文件也可以继续发送普通键值对
			django后端会将该编码格式中符合username=jason&password=123格式数据
			还是解析放到request.POST中  而针对文件数据则会解析放到request.FILES
		application/json
			传输的数据与编码格式一定要保持一致 不要骗人家
		
	ajax发送jason格式数据
		1.修改contentType参数
			urlencoded  >>>  application/json
		2.数据要处理成json格式
			JSON.stringify()     
		
		django后端针对json格式的数据 并不会做任何的处理操作
		数据就以二进制的形式存放在request.body中
		需要你自己手动处理该数据
			其实jason.loads可以直接反序列化符合json格式的二进制数据
				解码 + 反序列化
	
	ajax发送文件
		1.利用内置对象FormData
		2.需要额外修改两个参数的值
			processData:false
			contentType:false
		3.data只需要放FormData生成的对象即可
		
		如何往FormData的对象中添加数据
			formdata_obj = new FormData()
			# 普通键值
			formdata_obj.append(‘username‘,‘jason‘)
			formdata_obj.append(‘password‘,‘123‘)
			# 文件
			formdata_obj.append(‘myfile‘,$(‘input[type="file"]‘)[0].files[0])
			
			django后端能够自动识别FormData对象
			django后端会将该编码格式中符合username=jason&password=123格式数据
			还是解析放到request.POST中  而针对文件数据则会解析放到request.FILES
			
		
	ajax结合sweetalert 
		自己练习
			
		
	批量插入数据
		bulk_create()
		# 效率极低的
		for i in range(1000):
			models.User.objects.create(**kwargs)
		
		# 效率提升N多倍
		b_list = []
		for i in range(100000):
			b_list.append(modes.User(**kwargs))
		models.User.objects.bulk_create(b_list)

	自定义分页器
		推导思路
			1.利用queryset对象支持切片操作
			2.一页展示多少条数据 一共需要多少页 起始位和终止位 当前页
				per_page_num
				start_page
				end_page
				current_page
				# 上面四个参数的数学关系
			3.前端页面做一个分页器的样式 然后点击即可查看对应页
			4.到底需要渲染多少页
				divmod
			5.如何限制前端页面展示的页码数
				奇数位
		
		自定义分页器的使用方法
			1.将封装好的分页器代码直接拷贝
			2.
				# 1.生成一个分页器对象
				page_obj = Pagenation(current_page=request.GET.get(‘page‘,1),all_count=queryset.count())
				# 2.对真正的数据进行切片操作
				queryset_data = queryset[page_obj.start:page_obj.end]
				# 3.将切片之后的数据传递到前端页面
				return render(request,‘list.html‘,{"data":queryset_data})
			3.前端
				将原本页面上的queryset全部替换成queryset_data
				{{ page_obj.page_html|safe }}
		
	

forms组件
	小需求
		我们写一个注册页面 获取用户输入的用户名和密码
		用户点击注册发送到后端做用户名密码的校验
		用户名中不能包含金瓶			不符合社会主义核心价值观
		密码不能为空					你个DSB,密码怎么能为空
		
		1.手写获取用户输入的前端页面代码					渲染页面
		2.后端获取用户数据并做合法性校验					校验数据
		3.将校验之后的结果渲染到前端页面					展示信息
		
		
	forms组件
		1.渲染页面
		2.校验数据
		3.展示信息
		
		
		你需要先写一个类
			from django import forms


			class MyRegForm(forms.Form):
				# 用户名最少3位最多8位
				username = forms.CharField(max_length=8,min_length=3)
				password = forms.CharField(max_length=8,min_length=3)
				# email字段必须填写符合邮箱格式的数据
				email = forms.EmailField()
		
		如何校验数据
			# 1.传入待校验的数据  用自己写的类 传入字典格式的待校验的数据
			form_obj = views.MyRegForm({‘username‘:‘jason‘,‘password‘:‘12‘,‘email‘:‘123456‘})
			# 2.判断数据是否符合校验规则
			form_obj.is_valid()  # 该方法只有在所有的数据全部符合校验规则才会返回True
			False
			# 3.如何获取校验之后通过的数据
			form_obj.cleaned_data
			{‘username‘: ‘jason‘}
			# 4.如何获取校验失败及失败的原因
			form_obj.errors
			{
			 ‘password‘: [‘Ensure this value has at least 3 characters (it has 2).‘],
			 ‘email‘: [‘Enter a valid email address.‘]
			 }
			Out[16]: {}

# 5.注意 forms组件默认所有的字段都必须传值 也就意味着传少了是肯定不行的 而传多了则没有任何关系 只校验类里面写的字段 多传的直接忽略了
form_obj = views.MyRegForm({‘username‘: ‘jason‘, ‘password‘: ‘123456‘})
form_obj.is_valid()
Out[12]: False
form_obj.errors
Out[18]: {‘email‘: [‘This field is required.‘]}

form_obj = views.MyRegForm({‘username‘: ‘jason‘, ‘password‘: ‘123456‘, "email": ‘123@qq.com‘, "hobby": ‘hahahaha‘})
form_obj.is_valid()
Out[14]: True
form_obj.cleaned_data
Out[15]: {‘username‘: ‘jason‘, ‘password‘: ‘123456‘, ‘email‘: ‘123@qq.com‘}
form_obj.errors
		
		如何渲染页面
			你需要先写一个类
			
			forms组件只帮你渲染获取用户输入(输入 选择 下拉 文件)的标签 不渲染按钮和form表单标签
			渲染出来的每一个input提示信息都是类中字段首字母大写
			
			<p>第一种渲染方式:多个p标签  本地测试方便 封装程度太高了 不便于扩展</p>
			{{ form_obj.as_p }}
			{{ form_obj.as_ul }}
			{{ form_obj.as_table }}

			<p>第二种渲染方式:  扩展性较高 书写较为繁琐</p>
			<label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label>
			{{ form_obj.username }}
			{{ form_obj.password.label }}{{ form_obj.password }}
			{{ form_obj.email.label }}{{ form_obj.email }}

			<p>第三种渲染方式  推荐使用</p>
			{% for form in form_obj %}
				<p> {{ form.label }}{{ form }}</p>
			{% endfor %}
		
		如何渲染错误信息
			前端
				<form action="" method="post" novalidate>
					{% for form in form_obj %}
					<p>
						{{ form.label }}{{ form }}
						<span>{{ form.errors.0 }}</span>  # 这个是模板语法 索引不会出现超出报错
					</p>
					{% endfor %}
					<input type="submit">
				</form>
			
			后端
				def reg(request):
					# 1 先生成一个空的类对象
					form_obj = MyRegForm()
					if request.method == ‘POST‘:
						# 3 获取用户数据并交给forms组件校验  request.POST
						form_obj = MyRegForm(request.POST)
						# 4 获取校验结果
						if form_obj.is_valid():
							return HttpResponse(‘数据没问题‘)
						else:
							# 5 获取校验失败的字段和提示信息
							print(form_obj.errors)

					# 2 直接将该对象传给前端页面
					return render(request,‘reg.html‘,locals())
		
		
		
		
	
	数据校验一个前后端都得有 但是前端的校验弱不禁风 可有可无
	而后端的校验则必须非常全面
	
	
	如何取消浏览器自动帮我们校验的功能
	form表单取消前端浏览器自动校验功能 
		<form action="" method="post" novalidate>
			
		
	
	常用参数
		label    			input的提示信息
		error_messages   	自定义报错的提示信息
		required     		设置字段是否允许为空
		initial             设置默认值
		widget              控制type类型及属性
			widget=forms.widgets.TextInput(attrs={‘class‘:‘form-control c1  c2‘})
			widget=forms.widgets.PasswordInput(attrs={‘class‘:‘form-control‘})
	

	钩子函数
		全局钩子(针对多个字段)
			校验密码与确认面是否一致
		
		
		局部钩子(针对单个字段)
			校验用户名中不能包含666
			
		# 全局钩子
		def clean(self):
			# 校验密码和确认密码是否一致
			password = self.cleaned_data.get(‘password‘)
			confirm_password = self.cleaned_data.get(‘confirm_password‘)
			if not password == confirm_password:
				# 展示提示信息
				self.add_error(‘confirm_password‘,‘两次密码不一致‘)
			return self.cleaned_data

		# 局部钩子
		def clean_username(self):
			username = self.cleaned_data.get(‘username‘)
			if ‘666‘ in username:
				self.add_error(‘username‘,‘光喊666是不行的‘)
			return username
	
		# 如果你想同时操作多个字段的数据你就用全局钩子
		# 如果你想操作单个字段的数据 你就用局部钩子
		
	
	forms补充知识点
		正则校验
			phone = forms.CharField(
				validators=[
					RegexValidator(r‘^[0-9]+$‘, ‘请输入数字‘),
					RegexValidator(r‘^159[0-9]+$‘, ‘数字必须以159开头‘)
				]
			)
		
		其他字段渲染 了解即可 做到用时去哪拷贝即可!!!




	django操作cookie与session
	
	cookie与session的作用
		保存信息
	
	当你第一次登陆成功之后 服务端给你返回了一个随机字符串
	保存客户端浏览器上 之后再次朝服务端发请求 只需要携带该随机字符串
	服务端就能够识别当前用户身份
	超时时间的概念
	
	cookie虽然是保存在客户端的浏览器上的 但是是服务端设置的
	浏览器也是可以拒绝服务端对要求 不保存cookie
	
		
	cookie
		保存在客户端浏览器上的键值对
		return HttpResponse(‘...‘)
		
		return render(...)
		
		return redirect(...)
		
		# 变形
		obj = HttpResponse(‘...‘)
		return obj
		
		obj1 = render(...)
		return obj1
		
		obj2 = redirect(...)

		设置cookie
			obj.set_cookie()
		获取cookie
			request.COOKIES.get()
		删除cookie
			obj.delete_cookie()
	
	
	
	
	print(‘request.path_info:‘,request.path_info)  # 只拿路径部分 不拿参数
	print(‘request.get_full_path():‘,request.get_full_path())  # 路径加参数
		request.path_info: /home/

		request.get_full_path(): /home/?username=jason&password=123
		
	
	session
		保存在服务端上的键值对
		
		设置
			request.session[‘key‘] = value
			"""
			1.django内部会自动生成一个随机字符串
			2.去django_session表中存储数据 键就是随机字符串 值是要保存的数据(中间件干的)
			3.将生成好的随机字符串返回给客户端浏览器   浏览器保存键值对
				sessionid  随机字符串
			"""
			
		获取
			request.session.get(‘key‘)
			"""
			1.django会自动取浏览器的cookie查找sessionid键值对 获取随机字符串
			2.拿着该随机字符串取django_session表中比对数据
			3.如果比对上了 就将随机字符串对应的数据获取出来并封装到request.session供用户调用
			"""
		
		django中默认的session超时时间为14天
		
		# 设置会话Session和Cookie的超时时间
		request.session.set_expiry(value)
			* 如果value是个整数,session会在些秒数后失效。
			* 如果value是个datatime或timedelta,session就会在这个时间后失效。
			* 如果value是0,用户关闭浏览器session就会失效。
			* 如果value是None,session会依赖全局session失效策略。

		# 删除当前会话的所有Session数据
		request.session.delete()
		  
		# 删除当前的会话数据并删除会话的Cookie。  推荐使用
		request.session.flush() 
			这用于确保前面的会话数据不可以再次被用户的浏览器访问
			例如,django.contrib.auth.logout() 函数中就会调用它。
		
		session是保存在服务端
			

		作业
			利用session完成用户登录
			基于session完成登录跳转
		
		django_session表你还可以把它当成是一个临时的仓库
		
		
		
		
		
		
		
		
			
			
			
			
			
			
			
	
				
				
				
				
				
				
				
				
				
				
				
				
				
				
				
				
				
				
				
				
				
				
				



	


	
	
	
	
	
	
	
	
	
	
	
	

  

以上是关于111的主要内容,如果未能解决你的问题,请参考以下文章

算法手撕代码111~120

微信小程序代码片段

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

编写高质量代码改善C#程序的157个建议——建议111:避免双向耦合