Django进阶之Form组件

上周内容回顾
1.MTV与MVC
MTV
M:模型层(models)
T:模板层(templates)
V:视图层(views)
MVC
M:模型层(models)
V:视图层(views)
C:控制层(Controller)

2.多对多关系三种创建方式

第一种(全自动):
			author = models.ManyToManyField(to='Author')
		第二种(纯手动):
			class Book(models.Model):
				name = models.CharField(max_length=32)
			class Author(models.Model):
				name = models.CharField(max_length=32)	
			class Book2Author(models.Model):
				book = models.ForeignKey(...)
				author = models.ForeignKey(...)
		第三种(半自动):
			class Book(models.Model):
				name = models.CharField(max_length=32)
				# 多对多字段可以写在任意一方
				author = models.ManyToManyField(to='Author',through='Book2Author',through_fields=('book','author'))
			class Author(models.Model):
				name = models.CharField(max_length=32)
				# 多对多字段可以写在任意一方				
				author = models.ManyToManyField(to='Book',through='Book2Author',through_fields=('author','book'))
			class Book2Author(models.Model):
				book = models.ForeignKey(...)
				author = models.ForeignKey(...)
			# ps:半自动不支持多对多字段的增删改查方法 add(),set(),remove(),clear()
	
3.contentType参数
	前后端传输数据的编码格式
		1.urlencoded(form表单与ajax默认的数据提交编码格式)  
			数据格式 name='jason'&password='123'
			django后端识别到urlencoded数据格式将其处理封装到了request.POST
		2.formdata  传输文件
			支持传普通键值对也可以传文件
			普通键值还是处理放到request.POST中
			文件数据处理放到request.FILES中
		3.application/json(ajax支持)
			JSON.stringify({'name':'jason'})
			django后端对于json格式的数据不做任何处理,就将原生的二进制数据存在request.body中,让你自己手动处理
				先解码再反序列化
		
4.ajax
	异步提交(github注册示例)
	局部刷新
	
	四个基本参数
		url:'',  # 控制数据提交的地址,不写默认往当前位置提交
		type:'get',  # 控制的是数据的提交方式 get,post,。。。
		data:{'name':'jason'}  # 提交的数据
		success:function(data){
			# 做局部刷新的操作
			alert(data)
		}
	
	$('#b1').click(function(){
		$.ajax({
			url:'',  # 控制数据提交的地址,不写默认往当前位置提交
			type:'get',  # 控制的是数据的提交方式 get,post,。。。
			contentType:'application/json',
			data:JSON.stringify({'name':'jason'}),  # 提交的数据
			success:function(data){
				# 做局部刷新的操作
				alert(data)
			}
		})
	
	
	})
	
	ajax发送文件
		1.利用一个js内置对象FormData
		2.这个FormData即可以传普通的键值也可以传文件
		3.需要修改两个默认参数processData,contentType
		4.获取input框存储的文件数据$('input[type="file"]')[0].files[0]
	
	$('#b1').click(function(){
		# 先生成一个内置对象
		var formdata = new FormData();
		formdata.append('键','值');
		formdata.append('myfile',$('input[type="file"]')[0].files[0]);
		$.ajax({
			url:'',  # 控制数据提交的地址,不写默认往当前位置提交
			type:'get',  # 控制的是数据的提交方式 get,post,。。。
			contentType:false,
			processData:false,
			data:JSON.stringify({'name':'jason'}),  # 提交的数据
			success:function(data){
				# 做局部刷新的操作
				alert(data)
			}
		})
	
	
	})
	
	
	
	批量插入(bulk_create())
	l = []
	for i in range(1000000):
		l.append(user_obj)
	
	g = (models.User(name='%s'%i)  for i in range(1000000))
	
	
	自定义分页器
		后端
			book_list = models.Book.objects.all()
			page_obj = 自定义类(current_page=request.GET.get('page',1),all_count=book_list.count())
			book_queryset = book_list[page_obj.start:page_obj.end]
		前端
			将book_list全部替换为book_queryset
			渲染分页器样式
			{{ page_obj.page_html|safe }}
			
			
	补充
		import importlib
		s = 'xxx.b'
		res = importlib.import_module(s)

今日内容
django form组件

注册功能
1.渲染前端标签获取用户输入 >>> 渲染标签
2.获取用户输入传递到后端校验 >>> 校验数据
3.校验未通过展示错误信息 >>> 展示信息

校验数据(前后端都可以校验)
校验前端后端都可以做,但是前端可以不做,后端必须得做!!!

django form组件
1.渲染标签
2.校验数据
3.展示信息

	校验数据
		第一步需要一个form类
			from django import forms

			class MyForm(forms.Form):
				name = forms.CharField(max_length=6)
				password = forms.CharField(max_length=8,min_length=3)
				email = forms.EmailField(required=True)
		第二步实例化form对象
			form_obj = MyForm({'name':'jason'})
		
		第三步查看数据校验是否合法
			form_obj.is_valid()  # 只有当所有的字段都校验通过才会返回True
		
		第四步查看校验错误的信息
			form_obj.errors  # 这个里面放的是所有校验未通过的字段及错误提示
			"""
			{
			'name': ['Ensure this value has at most 6 characters (it has 7).'], 
			'password': ['Ensure this value has at least 3 characters (it has 2).'], 
			'email': ['Enter a valid email address.']
			}

			"""
		第五步查看校验通过的数据
			form_obj.cleaned_data  # 符合校验规则数据都会被放到该对象中
		ps:form组件校验数据的规则从上往下依次取值校验
			校验通过的放到cleaned_data
			校验失败的放到errors
		注意:
			form中所有的字段默认都是必须传值的(required=True)
			校验数据的时候可以都传(多传的数据不会做任何的校验>>>不会影响form校验规则)
	
	
	渲染标签
		form组件只帮你渲染获取用户输入的标签,不会帮你渲染提交按钮,需要手动添加
		<h1>第一种渲染方式(可扩展性较差)</h1>
		{{ form_obj.as_p }}
		{{ form_obj.as_ul }}
		
		<h1>第二种渲染方式</h1>
		<form action="">
			<p>{{ form_obj.name.label }}{{ form_obj.name }}</p>
			<p>{{ form_obj.password.label }}{{ form_obj.password }}</p>
			<p>{{ form_obj.email.label }}{{ form_obj.email }}</p>
			<input type="submit">
		</form>
		
		<h1>第三种渲染标签的方式</h1>
			<form action="">
				{% for foo in form_obj %}
					<p>{{ foo.label }}{{ foo }}</p>
				{% endfor %}
			</form>
	
	前端取消校验
		<form action="" method="post" novalidate>
		</form>
	
	
	form组件提交数据如果数据不合法,页面上会保留之前用户输入的信息
	在使用form组件对模型表进行数据校验的时候,只需要保证字段一致
	那么在创建的对象的时候你就直接**form_obj.cleaned_data
	
	<form action="" method="post" novalidate>
		{% for foo in form_obj %}
			<p>
				{{ foo.label }}{{ foo }}
				<span>{{ foo.errors.0 }}</span>
			</p>
		{% endfor %}
		<input type="submit">
	</form>
	
	
	# 钩子函数
		# 局部钩子函数  (单个字段的校验利用局部钩子函数)
		def clean_name(self):
			name = self.cleaned_data.get('name')
			if '666' in name:
				self.add_error('name','光喊666是不行的,要有真实力!')
			return name  # return还是要加上的,兼容性考虑

		# 全局钩子函数  (多个字段的校验利用全局钩子函数)
		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',"两次密码不一致,你这个dsb!")
			return self.cleaned_data
	
	
	
	
	# 设置标签样式
	from django import forms
	from django.forms import widgets
	password = forms.CharField(max_length=8,min_length=3,error_messages={
						'max_length': '密码最长8位',
						'required': '密码不能为空',
						'min_length':'密码最少3位'
						},widget=widgets.PasswordInput(attrs={'class':'c1 form-control'}))
	
	
			hobby = forms.ChoiceField(
			choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
			label="爱好",
			initial=3,
			widget=forms.widgets.Select()
		)
		hobby1 = forms.MultipleChoiceField(
			choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
			label="爱好",
			initial=[1, 3],
			widget=forms.widgets.SelectMultiple()
		)

		keep = forms.ChoiceField(
			label="是否记住密码",
			initial="checked",
			widget=forms.widgets.CheckboxInput()
		)


django操作cookie,session
	http协议四大特性
		1.基于TCP/IP作用于应用层的协议
		2.基于请求响应
		3.无状态
		4.无连接
		
	
	
	
	
	cookie
		保存在客户端浏览器上的键值对
	
	
	session
		保存在服务端上的键值对
		服务端产生随机的串儿返回给客户端,服务端找一个地方将串儿与对应的信息存起来{'随机字符串':'敏感信息'}
		
		
		
		
	django
		return HttpResponse()
		return render()
		return redirect()
	
	
		obj = HttpResponse()
		return obj
		obj = render()
		return obj
		obj = redirect()
		return obj
	
		
		设置cookie
			obj.set_cookie()  # 给浏览器设置cookie
		
		获取cookie
			request.COOKIE.get('name')
			request.COOKIE['name']
	
	
	
	def login(request):
		if request.method == 'POST':
			username = request.POST.get('username')
			password = request.POST.get('password')
			if username == 'jason' and password == '123':
				old_path = request.GET.get('next')
				if old_path:
					obj = redirect(old_path)
				else:
					obj = redirect('/home/')
				# 用户登录成功 朝浏览器设置一个cookie
				obj.set_cookie('name','jason',expires=7*24*3600)
				return obj
		return render(request,'login.html')
	
	from functools import wraps
	def login_auth(func):
		@wraps(func)
		def inner(request,*args,**kwargs):
			# 校验cookie
			# print(request.get_full_path())
			old_path = request.get_full_path()
			if request.COOKIES.get('name'):
				return func(request,*args,**kwargs)
			return redirect('/login/?next=%s'%old_path)
		return inner
	
	
	def logout(request):
		rep = redirect("/login/")
		rep.delete_cookie("user")  # 删除用户浏览器上之前设置的usercookie值
		return rep
	
	set_cookie()
	request.COOKIES
	delete_cookie
	
	
	
	
	
	
	
	session
		设置session
			request.session['name'] = 'jason'
			# 1.先生成一个随机的字符串
			# 2.在django session表中存储该随机字符串与数据的记录
			# 3.将随机的字符串发送给客户端浏览器
			
		获取session
			request.session.get('name')
			# 1.django自动获取浏览器随机字符串取django session表里面比对
			# 2.如果比对成功 会将当前随机字符串对应的数据赋值给request.session
			# 3.通过request.session操作该数据(数据不存在也不会影响我们的业务逻辑)
	
	浏览器会设置一个键为sessionid来存放session值
			
	
	# 删除当前会话的所有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失效策略。
	
	
	
django默认的session存活时间是两周(14天)******

猜你喜欢

转载自blog.csdn.net/weixin_43183295/article/details/92703964