首页 > 编程语言 > 详细

python的Web框架,会话保持及Form表单

时间:2019-03-21 11:31:52      阅读:121      评论:0      收藏:0      [点我收藏+]

会话

从打开浏览器访问到关闭浏览器,这就是一次会话。

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

 

无需其他配置,直接在页面中反馈

技术分享图片

 

python的Web框架,会话保持及Form表单

原文:https://www.cnblogs.com/hua888/p/10570199.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!