【Django2.0学习笔记】24.使用Django Form表单

24、使用Django Form表单

1、Django Form的作用

Django用Form类描述html表单,帮助或简化操作

  • 1、接收和处理用户提交的数据
    • 可检查提交的数据
    • 可将数据转换成Python的数据类型
  • 2、可自动生成html代码
    在这里插入图片描述

打开具体博客页面,有登录框,那如果我们在其他地方需要登录才能继续操作,那我们就得再写一个form标签,每个需要登录的地方都这样做的话,就比较麻烦、分散。这里我们可以把登录专门放到一个页面,不管哪个地方需要登录,我我们点击那个按钮或者链接,它就跳转到登录页面,登录完成之后再跳转回来,当然这里也可以做成那种弹窗式小窗口,在小窗口登录,这些都是可以实现的。这里我们用第一种方式 跳转页面
在templates下新建登录页面login.html,写入如下代码:

<!-- C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\templates\login.html -->
{% extends 'base.html' %}
{% load staticfiles %}

{% block title %}
	我的网站 | 登录
{% endblock %}

{% block nav_home_active %}active{% endblock %}

{% block content %}
    <form action="{% url 'login' %}" method="POST">
		{% csrf_token %}
		<span>用户名:</span>
		<input type="text" name="username"><!--text文本框类型,password密码框,submit按钮类型-->
		<span>密码:</span>
		<input type="password" name="password">
		<input type="submit" value="登录">
	</form>
{% endblock %}

接着我们要让blog_detail.html页面可以访问这个登录页面链接,我们打开全局url设置mysite/urls.py,这里有一条处理登录的方法 views.login,那我们修改这个方法,mysite/views.py如下:在这里插入图片描述
在这里插入图片描述

修改blog_detail.html如下:
在这里插入图片描述

刷新页面:在这里插入图片描述
在这里插入图片描述
接着我们要开始实现用Django Form去做东西

2、Django Form的使用

  • 创建forms.py文件
  • 字段 --> html input 标签
  • 每个字段类型都有一个适当的默认Widget类
from django import forms
class NameForm(forms.Form):
	your_name = forms.CharField(label='Your name', max_length=100)

在这里插入图片描述

这个forms文件需要放到某个app里,而这里我们没有创建登录相关的app,公共操作我们都是放在mysite这个文件夹下面,那么我们就可以在mysite这个文件夹下面新建forms文件写入如下代码:

# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\mysite\forms.py
from django import forms

class LoginForm(forms.Form):
	username = forms.CharField()
	password = forms.CharField()

接着我们打开登录页面的处理方法mysite/views.py:
在这里插入图片描述

再看前端页面login.html
在这里插入图片描述

刷新页面,点击“登录”
在这里插入图片描述

接着我们要做一些其他更改。比如上面页面里面的“username”“password”我们想要改成中文的
定制forms类,修改forms.py如下:
在这里插入图片描述
在这里插入图片描述

点击“登录”之后,哪个地方接收这个提交的数据,怎么样去操作?我们再多写一个链接多写一个处理方法的话,就有点繁琐。

这里form表单提交的方式跟普通加载页面不同,它是POST请求方式,而页面加载是GET请求方式,这两个不相同,那么我们可以让它提交到原来渲染页面的处理方法,判断是哪种类型,如果是POST这种类型的话,就说明是提交数据,如果是GET类型,就是加载页面
在这里插入图片描述

这里我们回到views.py处理方法,添加一个判断如下:

  • 如果请求方式是POST的话,则是提交数据;如果是其他行为,则是加载页面:
    • 提交数据部分。需要验证提交的数据是否有效:先接收数据,实例化。判断数据是否有效:
      • 如果有效,说明验证通过。如果验证通过,则登录。而登录需要用户名和密码,这两者可以通过login_form去获取,里面有个cleaned_data,字典形式,包含了我们所需要的字段信息。
      • 获取到用户名和密码这两个信息之后,就可以进行登录操作:
        • 判断user是否为None:
          • 不为None,说明验证通过,通过的话我们就登录
            • (1)登录成功之后有个重定向操作,重定向一个登录成功的页面。跳转方法我们引入redirect
            • 登录之后,这里我们就不能用之前referer了。我们要返回到进入登录页面之前的那个页面。这里数据最好要从页面传过来,有两种方式:1、get方式。url链接里写个 “?+参数” 形式。2、post方式。在login.html里面再多加一个字段,写明刚刚那个链接是什么。
            • 这里我们采用get方式,修改blog_detail.html如下。然后在views.py里面获取这个from参数就可以(若没有获取到,则默认跳转到首页)
            • (2)登录失败,重定向到一个错误页面。但这里页面跳来跳去不太好,我们可以利用form本身的错误集
              在这里插入图片描述

在页面点击“登录”后可以看到url里面多了链接信息,是点击跳转之前的页面url信息:
在这里插入图片描述

修改mysite\views.py如下:
在这里插入图片描述
在这里插入图片描述

刷新页面,点击“登录”,随便输入一个错误的用户名和密码登录
在这里插入图片描述

如果输入正确的用户名和密码,登录成功后,则跳转到原登录前的页面:
在这里插入图片描述

再回到views,继续写 验证不通过 的部分:
在这里插入图片描述

from .forms import LoginForm

def login(request):
	# 1)如果请求方式是POST的话,则是提交数据行为
	if request.method == 'POST':	
		# 2)提交数据部分。需要验证提交的数据是否有效
		# 3)先接收数据,实例化
		login_form = LoginForm(request.POST) # 将提交的数据 初始化一下
		# 4)判断数据是否有效
		if login_form.is_valid():	# 如果有效,说明验证通过
			# 5)如果验证通过,则登录。而登录需要用户名和密码,这两者可以通过login_form去获取,里面有个cleaned_data,字典形式,包含了我们所需要的字段信息
			username = login_form.cleaned_data['username']
			password = login_form.cleaned_data['password']
			# 6)获取到用户名和密码这两个信息之后,就可以进行登录操作
			user = auth.authenticate(request, username=username, password=password)
			if user is not None:	# 不为None,说明验证通过,通过的话我们就登录,登录之后有个重定向操作,重定向一个登录成功的页面。跳转方法我们引入redirect
				auth.login(request, user)
				return redirect(request.GET.get('from', reverse('home')))	# 登录之后,这里我们就不能用之前referer了。我们要返回到进入登录页面之前的那个页面。
				# 这里数据最好要从页面传过来,有两种方式:1、get方式。url链接里写个 ?+参数 形式。2、post方式。在login.html里面再多加一个字段,写刚刚那个链接是什么
				# 这里我们采用get方式,修改blog_detail.html,然后在views.py里面获取这个from参数就可以(若没有获取到,则默认跳转到首页)
			
			# 登录失败,重定向到一个错误页面。但这里页面跳来跳去不太好,我们可以利用form本身的错误集
			else:	
				login_form.add_error(None, '用户名或密码不正确')	# 这里有两个参数:对应的字段名、错误信息
				# 之后,我们把form返回回去,它携带了上面加的错误信息“用户名或密码不正确”,就可以把它自动的显示到前端模板页面
				context = {}
				context['login_form'] = login_form
				return render(request, 'login.html', context)		
		# 如果无效,说明验证未通过。实例化login_form信息也会传给前端页面显示出来
		else:	
			context = {}
			context['login_form'] = login_form
			return render(request, 'login.html', context)
	# 其他行为,则是加载页面
	else:	
		# 实例化
		login_form = LoginForm() 
		# 创建前端页面
		context = {}
		context['login_form'] = login_form
		return render(request, 'login.html', context)	

代码整合优化:
在这里插入图片描述

def login(request):
	# 1)如果请求方式是POST的话,则是提交数据行为
	if request.method == 'POST':	
		# 2)提交数据部分。需要验证提交的数据是否有效
		# 3)先接收数据,实例化
		login_form = LoginForm(request.POST) # 将提交的数据 初始化一下
		# 4)判断数据是否有效
		if login_form.is_valid():	# 如果有效,说明验证通过
			# 5)如果验证通过,则登录。而登录需要用户名和密码,这两者可以通过login_form去获取,里面有个cleaned_data,字典形式,包含了我们所需要的字段信息
			username = login_form.cleaned_data['username']
			password = login_form.cleaned_data['password']
			# 6)获取到用户名和密码这两个信息之后,就可以进行登录操作
			user = auth.authenticate(request, username=username, password=password)
			if user is not None:	# 不为None,说明验证通过,通过的话我们就登录,登录之后有个重定向操作,重定向一个登录成功的页面。跳转方法我们引入redirect
				auth.login(request, user)
				return redirect(request.GET.get('from', reverse('home')))	# 登录之后,这里我们就不能用之前referer了。我们要返回到进入登录页面之前的那个页面。
				# 这里数据最好要从页面传过来,有两种方式:1、get方式。url链接里写个 ?+参数 形式。2、post方式。在login.html里面再多加一个字段,写刚刚那个链接是什么
				# 这里我们采用get方式,修改blog_detail.html,然后在views.py里面获取这个from参数就可以(若没有获取到,则默认跳转到首页)
			
			# 登录失败,重定向到一个错误页面。但这里页面跳来跳去不太好,我们可以利用form本身的错误集
			else:	
				login_form.add_error(None, '用户名或密码不正确')	# 这里有两个参数:对应的字段名、错误信息
	# 其他行为,则是加载页面
	else:	
		# 实例化
		login_form = LoginForm() 
		
	# 创建前端页面
	context = {}
	context['login_form'] = login_form
	return render(request, 'login.html', context)

forms.py还有更多的功能,除了定义字段之外,还可以进行一些验证,比如用户名或者密码是否正确,也可以放到这里进行验证。
验证操作放到forms里,登录操作放在views.py的login里
修改forms.py如下:
在这里插入图片描述

修改views.py如下:
在这里插入图片描述

我们回到login.html模板页面,可以看到渲染出来的页面比较丑比较简陋,我们进行一些优化处理,可以查看Bootstrap文档,搜索“form-control”查看 输入框组。

先修改forms.py如下,这里我们可以在shell下查看下:
在这里插入图片描述
在这里插入图片描述

修改login.html如下:
在这里插入图片描述
在这里插入图片描述

这里我们到这里就行,也可以加一个面版,查看Bootstrap文档里面的“带标题的面版”
在这里插入图片描述

修改login.html如下:
在这里插入图片描述

完善forms.py如下:
在这里插入图片描述
在这里插入图片描述

我们如果想要去掉“用户名”“密码”后面的冒号,我们需要将login.html修改如下:
在这里插入图片描述

另外,将登录的错误信息显示出来,修改login.html如下:
在这里插入图片描述

刷新页面,随便输入用户名和密码:
在这里插入图片描述

至此,登录部分的代码写完了。

另外我们要写的是注册:
同样的,可以在forms.py加注册的内容:
在这里插入图片描述

接下来我们要添加链接、处理方法、对应的模板页面

修改mysite/views.py如下:
在这里插入图片描述

修改mysite/urls.py如下:
在这里插入图片描述

在templates下新建register.html(复制login.html,稍做修改即可):

<!-- C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\templates\register.html -->
{% extends 'base.html' %}
{% load staticfiles %}

{% block title %}
	我的网站 | 注册
{% endblock %}

{% block nav_home_active %}active{% endblock %}

{% block content %}
    <!-- <form action="{% url 'login' %}" method="POST">  这里的action链接如果是指向自己的话,可以不写或者只写一个#号-->
    <div class="container">
    	<div class="row">
    		<div class="col-xs-4 col-xs-offset-4">
    			<div class="panel panel-default">
					<div class="panel-heading">
						<h3 class="panel-title">注册</h3>
					</div>
					<div class="panel-body">
						<form action="" method="POST">
							{% csrf_token %}
							{% for field in reg_form %}
							<label for="{{ field.id_for_label }}">{{ field.label }}</label>
								{{ field }}
								<p class="text-danger">{{ field.errors.as_text }}</p>
							{% endfor %}
							<span class="pull-left text-danger">{{ login_form.non_field_errors }}</span>
							<input type="submit" value="注册" class="btn btn-primary pull-right">
						</form>
					</div>
				</div>	
    		</div>					
    	</div>
    </div>

{% endblock %}

接着回头来完善views.py里面的register处理方法:
在这里插入图片描述

接着在博客详情模板页面加上一个注册的选项
修改blog_detail.html如下:
在这里插入图片描述

刷新页面
在这里插入图片描述

点击“注册”
在这里插入图片描述

以下测试注册功能:
(1)用户名只输入一位:
在这里插入图片描述
(2)用户名输入已经存在的用户
在这里插入图片描述
(3)邮箱只输入一位:
在这里插入图片描述
(4)密码只输入一位:
在这里插入图片描述
(5)两次密码输入不一致
在这里插入图片描述
(6)成功注册后,页面跳转至
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值