d:/python/demo3
目标
- form表单
- get/post
- Request对象
- 利用HTML表单开发注册功能
- Django表单改造注册功能
- 数据绑定与校验(了解)
- 数据验证错误信息(了解)
- 实战任务
表单
表单有如下特征:
- 1、通过各种<input>、<select>等标签进行数据与参数的对应,用来作为数据载体,传递数据。
- 2、在<form>标签中的action属性定义url请求的地址。
- 3、在<form>标签中的method属性定义Http method。
get/post
get/post及区别略
Request对象
每个view函数的第一个参数是一个HttpRequest对象。
request对象的属性
request.scheme
代表请求的方案,http或者https
request.path
请求的路径,比如请求127.0.0.1/org/list,那这个值就是/org/list
request.method
表示请求使用的http方法,GET或者POST请求
request.encoding
表示提交数据的编码方式
request.GET
获取GET请求
request.POST
获取post的请求,比如前端提交的用户密码,可以通过request.POST.get()来获取
另外:如果使用 POST 上传文件的话,文件信息将包含在 FILES 属性中
request.COOKIES
包含所有的cookie
request.META
一个标准的Python 字典,包含所有的HTTP 首部。具体的头部信息取决于客户端和服务器,下面是一些示例:
CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。
CONTENT_TYPE —— 请求的正文的MIME 类型。
HTTP_ACCEPT —— 响应可接收的Content-Type。
HTTP_ACCEPT_ENCODING —— 响应可接收的编码。
HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。
HTTP_HOST —— 客服端发送的HTTP Host 头部。
HTTP_REFERER —— Referring 页面。
HTTP_USER_AGENT —— 客户端的user-agent 字符串。
QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。
REMOTE_ADDR —— 客户端的IP 地址。
REMOTE_HOST —— 客户端的主机名。
REMOTE_USER —— 服务器认证后的用户。
REQUEST_METHOD —— 一个字符串,例如"GET" 或"POST"。
SERVER_NAME —— 服务器的主机名。
SERVER_PORT —— 服务器的端口(是一个字符串)
request.user
一个 AUTH_USER_MODEL 类型的对象,表示当前登录的用户。
如果用户当前没有登录,user 将设置为 django.contrib.auth.models.AnonymousUser 的一个实例。你可以通过 is_authenticated() 区分它们
把request传给前端的时候,前端可以通过 {% if request.user.is_authenticated %}判断用户时候登录
request.session
一个既可读又可写的类似于字典的对象,表示当前的会话
利用form表单开发注册功能
接下来我们使用HTML表单,模拟一个用户注册功能,并演示如何使用HTML表单以及request对象:
- 用户的信息包括:用户名、密码、昵称、邮件地址、自我介绍。
- 访问/register注册页面,填写用户信息,点击[注册]按钮使用post方式提交表单。
- 提交后,后端校验数据有效性,用户名/密码/昵称为必填项,邮件地址中必须包含'@'。如果不满足有效性,则给出提示。
- 通过有效性验证后,页面跳转到新的欢迎页,并回显用户数据。
1)d:/python/demo3下新建Django工程
(略)
2)命令行输入以下命令,新建一个formapp,此应用用于测试form
python manage.py startapp formapp
3)setting.xml里注册formapp
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'formapp',
]
4)主urls加入以下语句
path('forms',include("formapp.urls")),
5)formapp下新建urls.py 交输入以下内容
from django.urls import path
from . import views
urlpatterns = [
path('', views.goregister, name='goregister'),
path('register', views.register),
]
6)views.py
def register(request):
errors = []
user = {}
if request.method == 'POST':
if not request.POST.get('nickname', ''):
errors.append('请输入昵称.')
if not request.POST.get('username', ''):
errors.append('请输入用户名.')
if not request.POST.get('password', ''):
errors.append('请输入密码.')
if request.POST.get('email') and '@' not in request.POST['email']:
errors.append('请输入有效的邮件地址.')
if not errors:
user = {
'nickname': request.POST['nickname'],
'username': request.POST['username'],
'password': request.POST['password'],
'email': request.POST.get('email', ''),
'self_intro': request.POST.get('self_intro', ''),
}
save_user(user)
# 使用post提交的表单,Django要求必须使用csrf标签,渲染模板时,请使用render方法
return render(request, 'success.html', user)
return render(request, 'register.html', {
'errors': errors,
'nickname': request.POST.get('nickname', ''),
'username': request.POST.get('username', ''),
'password': request.POST.get('password', ''),
'email': request.POST.get('email', ''),
'self_intro': request.POST.get('self_intro', ''),
})
def save_user(user):
# 省略保存用户实现过程
pass
7)页面
formapp/templates目录下新建register.html success.html
register.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Neuedu Django ch03</title>
</head>
<body>
{% if errors %}
<ul>
{% for error in errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
<!-- action属性不填写时,等同于将表单提交到当前页面的请求地址 -->
<form action="/forms/register" method="post">
{# csrf标签是Django提供的防止伪装提交请求的功能。POST方法提交的表格,必须有此标签。 #}
{% csrf_token %}
<p>昵称: <input type="text" name="nickname" value="{{ nickname }}" ></p>
<p>用户名: <input type="text" name="username" value="{{ username }}" ></p>
<p>密码: <input type="text" name="password" value="{{ password }}" ></p>
<p>邮件地址: <input type="text" name="email" value="{{ email }}" ></p>
<p>自我介绍: <textarea name="self_intro" rows="10" cols="50">{{ self_intro }}</textarea></p>
<input type="submit" value="注册">
</form>
</body>
</html>
success.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Neuedu Django ch03</title>
</head>
<body>
<h1>恭喜注册成功!您的用户信息如下:</h1>
<p>昵 称: {{ nickname }}</p>
<p>用 户 名: {{ username }}</p>
<p>邮件地址: {{ email }}</p>
<p>自我介绍: {{ self_intro }}</p>
</body>
</html>
8)运行效果
Django表单改造注册功能(中英文两套)
d:/python/demo3
上述功能,如果页面需要提交的字段比较多,后台views会特别麻烦。用Django表单组件可以简化这部分工作
Django带有一个form库,称为django.forms,这个库可以处理包括HTML表单显示以及验证的很多内容。接下来我们来深入了解一下form库,学习如何使用Django表单,最后试着使用它来重写我们的用户注册功能。
1)我们在settings目录创建一个python文件,form.py,继承自django.forms.Form,在RegisterForm中定义一些属性,与模型写法类似
from django import forms
class RegisterForm(forms.Form):
nickname = forms.CharField(max_length=20)
username = forms.CharField()
password = forms.CharField()
email = forms.EmailField(required=False)
self_intro = forms.CharField(required=False, widget=forms.Textarea)
class RegisterFormChinese(forms.Form):
nickname = forms.CharField(max_length=20, label='昵称')
username = forms.CharField(label='用户名')
password = forms.CharField(label='密码')
email = forms.EmailField(required=False, label='邮件地址')
self_intro = forms.CharField(required=False, widget=forms.Textarea, label='自我介绍')
2)改造views.py关键代码
from demo3.form import RegisterForm, RegisterFormChinese
def register(request):
# get请求访问页面时,返回空表单,post请求提交数据时进行表单验证和页面跳转
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
return render(request, 'success.html', {'form': form})
else:
form = RegisterForm()
return render(request, 'register.html', {'form': form})
def register_chinese(request):
if request.method == 'POST':
form = RegisterFormChinese(request.POST)
if form.is_valid():
# 将用户提交的表单回显,并设置不可编辑
# form.fields 返回一个OrderedDict
# 我们遍历这个存储着表单字段的字典,并通过widget.attrs设定他们的html属性
for f in form.fields.values():
f.widget.attrs['disabled'] = 'disabled'
return render(request, 'success.html', {'form': form})
else:
form = RegisterFormChinese()
return render(request, 'register_chinese.html', {'form': form})
3)改造register.html
<form action="/forms/register/" method="post">
{% csrf_token %}
<table>{{ form }}</table>
<input type="submit" value="Submit" />
</form>
4)register_chinese.html
<form action="/forms/register_chinese/" method="post">
{% csrf_token %}
<table>{{ form }}</table>
<input type="submit" value="提交" />
</form>
4)改造success.html
<body>
<h1>注册成功</h1>
<table>{{ form }}</table>
</body>
5)formapp.urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.goregister, name='goregister'),
path('register/', views.register),
path('register_chinese/', views.register_chinese),
]
6)启动服务
python manage.py runserver
7)浏览器输入地址测试
http://127.0.0.1:8000/forms/register/
http://127.0.0.1:8000/forms/register_chinese/
数据绑定与校验证(了解)
form.is_bound()属性查看表单对象是否已经绑定
form.is_valid()是否所有字段验证通过,返回True/False
数据验证错误信息(了解)
f.errors()提供了一个字段与错误消息相映射的字典表。
代码解释
我们将页面展示与页面提交的地址都设置为formapp/register
在视图中通过request对象的method方法判断页面请求的get/post方法,进行不同的操作。
当页面提交get请求时(直接访问url地址),初始化一个空的表单对象,并返回给页面。
当页面提交post请求时(通过页面html提交表单时),验证表单并跳转到成功页面。