Django 简明教程

Django - Form Processing

在 Django 中创建表单与创建模型非常相似。同样,我们只需要继承自 Django 类,而类属性将成为表单字段。我们将在 myapp 文件夹中添加一个 forms.py 文件来包含我们的应用表单。我们将创建一个登录表单。

Creating forms in Django, is really similar to creating a model. Here again, we just need to inherit from Django class and the class attributes will be the form fields. Let’s add a forms.py file in myapp folder to contain our app forms. We will create a login form.

myapp/forms.py

myapp/forms.py

#-*- coding: utf-8 -*-
from django import forms

class LoginForm(forms.Form):
   user = forms.CharField(max_length = 100)
   password = forms.CharField(widget = forms.PasswordInput())

如上所示,字段类型可以采用“widget”参数进行 html 渲染;在我们的案例中,我们希望密码隐藏,不显示。Django 中存在许多其他小组件: DateInput 用于日期, CheckboxInput 用于复选框等。

As seen above, the field type can take "widget" argument for html rendering; in our case, we want the password to be hidden, not displayed. Many others widget are present in Django: DateInput for dates, CheckboxInput for checkboxes, etc.

Using Form in a View

有两种 HTTP 请求,GET 和 POST。在 Django 中,作为参数传递给视图的请求对象有一个名为“method”的属性,其中设置请求的类型,可以通过 request.POST 词典访问通过 POST 传递的所有数据。

There are two kinds of HTTP requests, GET and POST. In Django, the request object passed as parameter to your view has an attribute called "method" where the type of the request is set, and all data passed via POST can be accessed via the request.POST dictionary.

我们将在 myapp/views.py 中创建一个登录视图 −

Let’s create a login view in our myapp/views.py −

#-*- coding: utf-8 -*-
from myapp.forms import LoginForm

def login(request):
   username = "not logged in"

   if request.method == "POST":
      #Get the posted form
      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。

The view will display the result of the login form posted through the loggedin.html. To test it, we will first need the login form template. Let’s call it login.html.

<html>
   <body>

      <form name = "form" action = "{% url "myapp.views.login" %}"
         method = "POST" >{% csrf_token %}

         <div style = "max-width:470px;">
            <center>
               <input type = "text" style = "margin-left:20%;"
                  placeholder = "Identifiant" name = "username" />
            </center>
         </div>

         <br>

         <div style = "max-width:470px;">
            <center>
               <input type = "password" style = "margin-left:20%;"
                  placeholder = "password" 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) 攻击。

The template will display a login form and post the result to our login view above. You have probably noticed the tag in the template, which is just to prevent Cross-site Request Forgery (CSRF) attack on your site.

{% csrf_token %}

一旦我们有了登录模板,就需要在表单处理后渲染的 loggedin.html 模板。

Once we have the login template, we need the loggedin.html template that will be rendered after form treatment.

<html>

   <body>
      You are : <strong>{{username}}</strong>
   </body>

</html>

现在,我们只需要我们的 URL 对即可开始:myapp/urls.py

Now, we just need our pair of URLs to get started: myapp/urls.py

from django.conf.urls import patterns, url
from django.views.generic import TemplateView

urlpatterns = patterns('myapp.views',
   url(r'^connection/',TemplateView.as_view(template_name = 'login.html')),
   url(r'^login/', 'login', name = 'login'))

在访问“/myapp/connection”时,我们将获得以下登录.html 模板渲染 −

When accessing "/myapp/connection", we will get the following login.html template rendered −

login html template

在表单发布时,表单有效。在我们的案例中,确保填写这两个字段,您将得到 −

On the form post, the form is valid. In our case make sure to fill the two fields and you will get −

form validation

如果您的用户名是 polo,并且您忘记了密码。您将收到以下消息 −

In case your username is polo, and you forgot the password. You will get the following message −

form invalid message

Using Our Own Form Validation

在以上示例中,在验证表单时 −

In the above example, when validating the form −

MyLoginForm.is_valid()

在我们的案例中,我们只使用了 Django 自身表单验证引擎,只确保字段是必需的。现在,我们尝试确保尝试登录的用户作为 Dreamreal 条目存在于我们的数据库中。为此,将 myapp/forms.py 更改为:

We only used Django self-form validation engine, in our case just making sure the fields are required. Now let’s try to make sure the user trying to login is present in our DB as Dreamreal entry. For this, change the myapp/forms.py to −

#-*- coding: utf-8 -*-
from django import forms
from myapp.models import Dreamreal

class LoginForm(forms.Form):
   user = forms.CharField(max_length = 100)
   password = forms.CharField(widget = forms.PasswordInput())

   def clean_message(self):
      username = self.cleaned_data.get("username")
      dbuser = Dreamreal.objects.filter(name = username)

      if not dbuser:
         raise forms.ValidationError("User does not exist in our db!")
      return username

现在,在调用 “isValid” 方法之后,只有当用户在我们的数据库中时,我们才会获得正确的结果。如果你想检查表单中的某个字段,只需添加一个以 “clean_” 开头的方法,然后将你的字段名称添加到你的表单类中。提升 forms.ValidationError 非常重要。

Now, after calling the "is_valid" method, we will get the correct output, only if the user is in our database. If you want to check a field of your form, just add a method starting by "clean_" then your field name to your form class. Raising a forms.ValidationError is important.