Django 表单
表单是用户和网站之间交互的最经典的方式。在 Django 中创建表单与创建模型非常相似。Django表单系统的核心组件是 Form 类。我们自定义的表单类都需要继承 Form类。
让我们在 app 中新建一个 forms.py 文件用来定义我们所有的应用程序表单。
首先我们创建一个用来登录的表单
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(max_length=100)
password = forms.CharField(widget=forms.PasswordInput())
如上所示,字段类型可以使用“widget”参数进行 html 渲染;在我们的例子中,我们希望密码被隐藏,而不是显示。Django 中还存在许多其他小部件:DateInput用于输入日期,CheckboxInput用于复选框等。
在视图中使用表单
HTTP 请求有两种,GET 和 POST。在 Django 中,作为参数传递给视图的请求对象有一个名为“method”的属性,其中设置了请求的类型,所有通过 POST 传递的数据都可以通过 request.POST 进行访问。
让我们在 app/views.py 中创建一个用于登录的视图
def login(request):
username = ""
if request.method == "POST":
# 获取使用 post 提交的表单
MyLoginForm = LoginForm(request.POST)
if MyLoginForm.is_valid():
username = MyLoginForm.cleaned_data['username']
else:
MyLoginForm = LoginForm()
return render(request, 'loggedin.html', {"username": username})
该视图显示使用表单登录之后的页面,该页面是由 loggedin.html 模板提供。 接下来我们写一个用于登录的模板,login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Django 表单登录界面 - 迹忆客</title>
</head>
<body>
<form name = "form" action = "/app/login/"
method = "POST" >{% csrf_token %}
<div style = "max-width:470px;">
<center>
<input type = "text" style = "margin-left:20%;"
placeholder = "输入用户名" name = "username" />
</center>
</div>
<br>
<div style = "max-width:470px;">
<center>
<input type = "password" style = "margin-left:20%;"
placeholder = "密码" name = "password" />
</center>
</div>
<br>
<div style = "max-width:470px;">
<center>
<button style = "border:0px; background-color:#4285F4; margin-top:8%;
height:35px; width:80%;margin-left:19%;" type = "submit"
value = "Login" >
<strong>Login</strong>
</button>
</center>
</div>
</form>
</body>
</html>
上面创建了一个登录的表单模板。我们看模板中的标签
{% csrf_token %}
这是用来防止跨站请求伪造 (CSRF) 攻击的。
我们已经有了登录的模板,下面我们新建登录后的模板页面 loggedin.html。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Django 登录之后页面 - 迹忆客</title>
</head>
<body>
{% if username != '' %}
You are : <strong>{{username}}</strong>
{% else %}
您登录失败
{% endif %}
</body>
</html>
接下来就剩下路由的定义了,下面我们在 app/urls.py 中定义路由如下
from django.views.generic import TemplateView, ListView
from . import views
urlpatterns = [
path('hello/', views.hello),
path('connection/', TemplateView.as_view(template_name='login.html')),
path('login/', views.login, name='login')
]
访问 /app/connection ,然后输入用户名和密码,表单提交如下
上面我们是输入了用户名和密码,如果实际情况中,我忘记了密码,或者没有填写密码。这时根据上面的例子,应该提示我们 登录失败
自定义表单验证
在上面的例子中,当验证表单时我们使用了 is_valid() 方法。
MyLoginForm.is_valid()
我们只使用了 Django 表单自带的验证引擎,在我们的例子中只是确保这些字段是必需的。现在让我们自定义一个简单的验证规则,确保登录的用户是 UserModel中的用户 。为此,我们需要更改 app/forms.py
class LoginForm(forms.Form):
username = forms.CharField(max_length=100)
password = forms.CharField(widget=forms.PasswordInput())
def clean_username(self):
username = self.cleaned_data.get("username")
dbuser = UserModel.objects.filter(name=username)
if not dbuser:
raise forms.ValidationError("User does not exist in our db!")
return username
现在,在调用“is_valid”方法后,Django会自动调用 clean_username 方法。如果我们输入的用户名在UserModel中有记录,则我们会获得正确的输出。如果想检查表单的某个字段,只需添加一个以“clean_”开头的方法,然后后面跟上你的字段 例如 clean_username。 username就是我们要检查的表单的字段。这里需要注意的是,触发 forms.ValidationError 是很有必要的。
我们看一下上面示例的结果