会话
从打开浏览器访问到关闭浏览器,这就是一次会话。
cookie 技术
cookie是保存在浏览器的,安全度比较低。
1 # 设置cookie范式,在view中设置 2 3 def index(request): 4 # 查看是否有num的这个cookie 5 num = request.COOKIES.get('num') 6 if num: 7 num = str(int(num)+1) 8 else: 9 num = '1' 10 11 response = render(request, 'teacher/index.html', context={ 12 'num':num 13 }) 14 # 设置cookie字段,max_age为浏览器保留的cookie时间(过期时间)。 15 response.set_cookie('num',num, max_age=10) 16 return response
session 技术
在settings中注册,且是做了数据库迁移的。存储的数据默认存储在django_sessions表中
1 INSTALLED_APPS = [ 2 'teacher.apps.TeacherConfig', 3 'django.contrib.admin', 4 'django.contrib.auth', 5 'django.contrib.contenttypes', 6 'django.contrib.sessions', #最新的版本中是默认注册了的。但需要检查是否注册 7 'django.contrib.messages', 8 'django.contrib.staticfiles', 9 ] 10 11 MIDDLEWARE = [ 12 'django.middleware.security.SecurityMiddleware', 13 'django.contrib.sessions.middleware.SessionMiddleware', #默认是添加了的 14 'django.middleware.common.CommonMiddleware', 15 'django.middleware.csrf.CsrfViewMiddleware', 16 'django.contrib.auth.middleware.AuthenticationMiddleware', 17 'django.contrib.messages.middleware.MessageMiddleware', 18 'django.middleware.clickjacking.XFrameOptionsMiddleware', 19 ]
设置session,view中配置
1 def login(request): 2 if request.method == 'POST' 3 username = request.POST.get('username','') 4 password = request.POST.get('password','') 5 if username == 'aaa' and password == '123456': 6 # 如果登录成功,则把当前的用户名保存在session中 7 request.session['name'] = username 8 9 # 设置过期时间set_expiry 10 request.session.set_expiry(10) 11 return redirect(reverse('teacher:index')) 12 13 # 如果在index的html中需要展示用户名的信息,则需要在index中获取session 14 # name = request.session.get('name'),然后在通过context传送到html中 15 16 17 # 设置退出 18 def logout(request): 19 request.session.flush() 20 return redirect(reverse('teacher:index')) 21 22 23 #应用于html的和之前的方式是一样的。{{ }}or{% %}
session 依赖于cookie,cookie存在客户端,session存在服务端。
简单的Form表单
在app下面创建一个forms.py的文件
1 # 导包 2 from django import forms 3 class RegisterForm(forms.Form): 4 username = forms.CharField(label='用户名', max_length=20) 5 password = forms.CharField(label='密码',max_length=10,min_length=6, 6 widget=forms.PasswordInput(attrs={'placeholder':'请输入长度为6-10位的密码'}), 7 error_messages={'min_length':'密码长度小于6位','max_length':'密码长度大于10位'}) 8 password_repeat = forms.CharField(label='请再次输入密码',widget=forms.PasswordInput()) 9 email = forms.EmailField(required=False) 10 11 def clean(self): 12 cleaned_data = super().clean() #继承父类的clean方法 13 14 # 从父类中检测处理过的数据 15 password = cleaned_data.get('password') 16 password_repeat = cleaned_data.get('password_repeat') 17 18 if password != password_repeat: 19 msg = '两次密码输入不一致' 20 self.add_error('password_repeat', msg) #把这个错误的信息加入到password_repeat这个字段中 21 22 23 解析: 24 form表单中的不同的字段将会生成不同的input类型,CharField默认对应text 25 字段名(变量)对应的html中input中的name 26 PasswordInput:被渲染成passwo的input标签,里面的内容可以和input一样的内容定制 27 label:对应的html中的label标签中的内容 28 error_messages:表示出错后的提示 29 required=False:可以不填写,表示可以是不填的选项
在view中应用:
1 # 从APP中导入 2 from teacher.forms import RegisterForm 3 def register(request): 4 # 判断method 5 if request.method == 'GET': 6 form = RegisterForm() #实例 7 8 9 if request.method == 'POST': 10 form = RegisterForm(request.POST) 11 if form.is_valid(): 12 return HttpResponse('注册成功') 13 14 return render(requerst, 'teacher/register.html', context={'form':form}) 15 16 17 18 解析: 19 RegisterForm(request.POST),会根据传进来的request的值来创建一个form,一个绑定的form 20 is_valid:自动会去根据配置好的去验证,调用此方法的时候,就会默认调用form里面的clean方法。 21
在html中应用:
1 <form action=""> 2 {% csrf_token %} 3 {{ form.as_p }} 4 <input type="submit" value="注册"> 5 </form>
form的标签和submit需要自己添加,其他的自己渲染。as_p代表用p标签包裹。
查看渲染后,代码是什么样式。
1 查看渲染后的代码 2 <form action="" method="post"> 3 <p><label for="id_username">用户名:</label> <input type="text" name="username" required id="id_username" maxlength="20"></p> 4 <p><label for="id_password">密码:</label> <input type="password" name="password" placeholder="请输入长度为6-10位的密码" required id="id_password" maxlength="10" minlength="6"></p> 5 <p><label for="id_password_repeat">请再次输入密码:</label> <input type="password" name="password_repeat" required id="id_password_repeat"></p> 6 <p><label for="id_email">Email:</label> <input type="email" name="email" required id="id_email"></p> 7 <input type="submit" value="注册"> 8 </form>
输出渲染的结果:
密码的判断输出方式
模型Form表单
同样写在forms.py的文件内
1 # 把需要的models模型导入 2 from teacher.models import Students,StudentsDetail
定义表单
1 # Students表单 2 class StudentForm(forms.ModelForm): 3 class Meta: 4 #不需要一个一个的编辑了,只需要用自带的方法即可,即排除 5 model = Students 6 7 # 表单内除了'is_deleted'这个字段外,其他的都需要,使用exclude方法 8 exclude = ['is_deleted'] 9 10 # StudentsDetail表单 11 class StudentDetailForm(forms.ModelForm): 12 class Meta: 13 model = StudentsDetail 14 15 # 表单内只需要这些字段,使用fields方法 16 fields = ['num', 'college']
在view中应用
1 # 导入需要的form模型表单 2 from teacher.forms import StudentForm, StudentDetailForm
编辑学生信息页面
1 def new_edit(request, pk): 2 # 获取当前编辑字段的信息 3 student = Students.objects.get(pk=pk) 4 5 form = StudentForm(instance=student) 6 7 try: 8 # 这里做出捕获异常,防止这个学生字段没有相对应的studentsdetail字段。 9 detail_form = StudentDetailForm(instance=student.studentsdetail) 10 11 except: 12 # 如果报错,说明这个学生还没有学生详情 13 14 # 生产一个空的详情 15 student_detail = StudentsDetail() 16 17 # 把两个表相关联起来,保存 18 student_detail.sudent = student 19 student_detail.save() 20 21 # 生成新的form表单 22 detail_form = StudentDetailForm(instance=student_detail) 23 24 *****此处的POST方法写在下面的POST请求方式操作中。 25 26 return render(request, 'teacher/new_student_edit.html', context={ 27 'section': section, 28 'student': student, 29 'form': form, 30 'detail_form': detail_form, 31 }) 32 33 34 解析: 35 instance:绑定一个信息,用于修改。 36 如果不写这个,则生成一个空的Form,用于添加。 37
html中整体应用
1 <form class="form-horizontal" method="post"> 2 {% csrf_token %} 3 {{ form.as_p }} 4 {{ detail_form.as_p }} 5 <div class="col-sm-offset-2 col-sm-10"> 6 <button type="submit" class="btn btn-default">提交</button> 7 </div> 8 </form>
html中分别渲染
1 <form class="form-horizontal" method="post"> 2 {% csrf_token %} 3 4 {% for field in form %} 5 <div class="form-group"> 6 7 <!--渲染出报错信息--> 8 {% for error in field.errors %} 9 <label for="{{ field.id_for_label }}" class="col-sm-2 control-label">{{ error }}</label> 10 {% endfor %} 11 12 <!--渲染出字段名--> 13 <label for="{{ field.id_for_label }}" class="col-sm-2 control-label">{{ field.label }}</label> 14 <div class="col-sm-2"> 15 16 <!--渲染出input标签内容--> 17 {{ field }} 18 </div> 19 </div> 20 {% endfor %} 21 22 23 {% for field in detail_form %} 24 <div class="form-group"> 25 {% for error in field.errors %} 26 <label for="{{ field.id_for_label }}" class="col-sm-2 control-label">{{ error }}</label> 27 {% endfor %} 28 <label for="{{ field.id_for_label }}" class="col-sm-2 control-label">{{ field.label }}</label> 29 <div class="col-sm-2"> 30 {{ field }} 31 </div> 32 </div> 33 {% endfor %} 34 35 <div class="col-sm-offset-2 col-sm-10"> 36 <button type="submit" class="btn btn-default">提交</button> 37 </div>
当前样式:
分别渲染样式:
添加css样式
当前是没有css的样式的,那如何添加样式呢,有一个方法我们可以看下,input的内容是怎么来的
# 通过这个方法可以看到,我们的input标签是什么样的,然后我们可以去操作他。 >>> form['name'].as_widget() <input type="text" name="name" value="哈哈哈" id="id_name" required maxlength="20"> # 如何给他添加class的属性?通过attrs字典的方式给他传入,就可以给这个input添加class >>> form['name'].as_widget(attrs={'class':'aaa'}) <input type="text" name="name" value="哈哈哈" id="id_name" required class="aaa" maxlength="20">
tags的添加方法
因为在html中用了{% %}方式添加,所以不好给其添加class,只有给他tags方法才好添加,现在,我们写一个tags方法来实现添加class。
1 # 在tags.py的文件中写添加方法 2 3 from django.template import Library 4 5 @register.simple_tag 6 def add_class(field, class_str): 7 return field.as_widget(attrs={'class':class_str})
html 中应用
1 <!--先load进来后,再使用标签--> 2 {% load customer_tags %} 3 4 <!--使用上面这个add_class标签,在for循环中添加使用--> 5 {% add_class field 'form-control' %}
使用之后样式:
GET输出的样式已经完成,那POST的样式如何完成的呢。
POST请求方式操作
view中的post判断
1 接上面的代码来写POST方法 2 3 if request.method == 'POST': 4 # 此处的instance必须等于前面对应的信息(student = Students.objects.get(pk=pk)),以保证GET的字段信息和POST的信息是获取的同一个信息。 5 form = StudentForm(request.POST, instance=student) 6 7 detail_form = StudentDetailForm(request.POST,instance=student.studentdetail) 8 9 # 验证,如果都验证成功,则保存。 10 if form.is_valid() and detail_form.is_valid(): 11 form.save() 12 detail_form.save() 13 return redirect(reverse('teacher:students')) 14 15 16 空Form保存示例: 17 # instance:绑定一个信息,用于修改。 18 # 如果不写这个,则生成一个空的Form,用于添加。 19 20 # 生成一个空的Form时在保存数据的时候。关联表简单示例如下: 21 22 if form.is_valid() and detail_form.is_valid(): 23 student = form.save() 24 25 # 加上commit=False,则不会真的保存到数据库,需要还需要关联外键 26 student_detail = detail.form.save(commit=False) 27 student_detail.student = student 28 student_detail.save() 29 return redirect(reverse('teacher:students'))
设置修改时的报错,model.py中配置,把英文报错修改为中文。
1 加上error_messages方法,设置的是重复的地方报错,出错在unique。 2 qq = models.CharField('QQ', max_length=20, unique=True, null=True, error_messages={'unique':'QQ号码重复'})
html中的整体应用
1 <form class="form-horizontal" method="post"> 2 {% csrf_token %} 3 4 <!--循环迭代出需要的字段--> 5 {% for field in form %} 6 7 <!--如果有error的提示,则对这个div添加class中的has-error--> 8 <div class="form-group {% if field.errors %}has-error{% endif %}"> 9 10 <!--对设置的error迭代循环添加--> 11 {% for error in field.errors %} 12 <label for="{{ field.id_for_label }}" class="control-label">{{ error }}</label> 13 {% endfor %} 14 15 循环生成展示的label字段 16 <label for="{{ field.id_for_label }}" class="col-sm-2 control-label">{{ field.label }}</label> 17 <div class="col-sm-2"> 18 19 使用tag标签来给input标签添加class 20 {% add_class field 'form-control' %} 21 </div> 22 </div> 23 {% endfor %} 24 25 26 {% for field in detail_form %} 27 <div class="form-group {% if field.errors %}has-error{% endif %}"> 28 {% for error in field.errors %} 29 <label for="{{ field.id_for_label }}" class="control-label">{{ error }}</label> 30 {% endfor %} 31 <label for="{{ field.id_for_label }}" class="col-sm-2 control-label">{{ field.label }}</label> 32 <div class="col-sm-2"> 33 {% add_class field 'form-control' %} 34 </div> 35 </div> 36 {% endfor %} 37 38 <div class="col-sm-offset-2 col-sm-10"> 39 <button type="submit" class="btn btn-default">提交</button> 40 </div> 41 </form>
加上之后的效果,可以渲染出报错时的效果。
用另一种方式的验证,在forms.py中配置
1 class StudentDetailForm(forms.ModelForm): 2 class Meta: 3 model = StudentsDetail 4 fields = ['num', 'college'] 5 6 def clean_num(self): 7 # 从验证之后的数据中获取num字段 8 data = self.cleaned_data.get('num') 9 10 # 一个简单的身份证验证,除最后一位数以外都是数字的,才是对的,其他则不对。 11 if not data[:-1].isdigit(): 12 raise forms.ValidationError('您输入的身份证号码不正确') 13 return data
无需其他配置,直接在页面中反馈