zoukankan      html  css  js  c++  java
  • 【django之form表单】

    一、构建一个表单

    假设你想在你的网站上创建一个简单的表单,以获得用户的名字。你需要类似这样的模板:

    <form action="/your-name/" method="post">
        <label for="your_name">Your name: </label>
        <input id="your_name" type="text" name="your_name">
        <input type="submit" value="OK">
    </form>

    这是一个非常简单的表单。实际应用中,一个表单可能包含几十上百个字段,其中大部分需要预填充,而且我们预料到用户将来回编辑-提交几次才能完成操作。

    我们可能需要在表单提交之前,在浏览器端作一些验证。我们可能想使用非常复杂的字段,以允许用户做类似从日历中挑选日期这样的事情,等等。

    这个时候,让Django 来为我们完成大部分工作是很容易的。

    Form表单的功能

    • 自动生成HTML表单元素
    • 检查表单数据的合法性
    • 如果验证错误,重新显示表单(数据不会重置)
    • 数据类型转换(字符类型的数据转换成相应的Python类型)

    二、在Django 中构建一个表单

    1、Form 类

    创建form组件

    复制代码
    from django import forms
    from django.forms import widgets
    from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
    class LoginForm(forms.Form):
        user=forms.CharField(label="用户名",min_length=3,max_length=8,
                             widget=widgets.TextInput(attrs={"class": "form-control"}),
                             error_messages={"min_length":"太短","required":"必填"})
    
        pwd=forms.CharField(label="密码",min_length=5,
                            widget=widgets.PasswordInput(attrs={"class":"form-control"}),
                            error_messages={"min_length":"太短", "required": "必填"}
                            )
    复制代码

     

    2、views.py

    如果访问视图的是一个GET 请求,它将创建一个空的表单实例并将它放置到要渲染的模板的上下文中。这是我们在第一个访问该URL 时预期发生的情况。

    如果表单的提交使用POST 请求,那么视图将再次创建一个表单实例并使用请求中的数据填充它:form = NameForm(request.POST)。这叫做”绑定数据至表单“(它现在是一个绑定的表单)。

    我们调用表单的is_valid()方法;如果它不为True,我们将带着这个表单返回到模板。这时表单不再为空(未绑定),所以HTML 表单将用之前提交的数据填充,然后可以根据要求编辑并改正它。

    如果is_valid()True,我们将能够在cleaned_data 属性中找到所有合法的表单数据。在发送HTTP 重定向给浏览器告诉它下一步的去向之前,我们可以用这个数据来更新数据库或者做其它处理。

    • if GET请求

    复制代码
    if GET请求:
                   login_form=LoginForm()
                   return render(request,"login_form.html",locals())
                   
                   渲染方式:
                          (1)   login_form.as_p
                           
                           (2)    推荐
                                  <form action="" method="post" novalidate>
                                        {% csrf_token %}
                                        <div class="form-group">
                                            <label for="">{{ login_form.user.label }}</label>
                                            {{ login_form.user }} <span>{{ login_form.errors.user.0 }}</span>
                                        </div>
                                        <div class="form-group">
                                            <label for="">{{ login_form.pwd.label }}</label>
                                            {{ login_form.pwd }} <span>{{ login_form.errors.pwd.0 }}</span>
                                        </div>
                                        <input type="submit">
                                    </form>
    复制代码
    • if POST 请求

    复制代码
                if POST 请求:
                
                        login_form=LoginForm(request.POST)
                        
                        if login_form.is_valid():
                             # 所有字段验证成功
                             # 所有请求数据:login_form.cleaned_data
                             
                        else:
                            #login_form.errors               # 字典:{"user":["","",]}    
                            #login_form.errors.get("user")   # 列表:["",""] 
                        
                            return render(request, "login_form.html", locals())
                            
                            
                            渲染:
                                <form action="" method="post" novalidate>
                                        {% csrf_token %}
                                        <div class="form-group">
                                            <label for="">{{ login_form.user.label }}</label>
                                            {{ login_form.user }} <span>{{ login_form.errors.user.0 }}</span>
                                        </div>
                                        <div class="form-group">
                                            <label for="">{{ login_form.pwd.label }}</label>
                                            {{ login_form.pwd }} <span>{{ login_form.errors.pwd.0 }}</span>
                                        </div>
                                        <input type="submit">
                                    </form>
    复制代码
    • is_valid()

    Form 的实例具有一个is_valid() 方法,它为所有的字段运行验证的程序。当调用这个方法时,如果所有的字段都包含合法的数据,它将:

    • 返回True
    • 将表单的数据放到cleaned_data属性中。
    复制代码
    is_valid:
            
                 self.errors={}
                 
                 self.cleaned_data={}
                 
                 
                 for name ,field in self.fields.items():
                 
                     if field(数据):
                        self.cleaned_data[name]="数据"
                         
                     else:
                        self.errors[name]="错误信息"
    复制代码

    钩子函数

    复制代码
        def clean_user(self):
            val=self.cleaned_data.get("user")
    
            import re
            # if not UserInfo.objects.filter(username=val):
            #     return val
            # else:
            #     raise ValidationError("")
    
            if not val.isdigit():
                return val
            else:
                raise ValidationError("用户名不能是纯数字!")
    
        def clean_pwd(self):
            val=self.cleaned_data.get("pwd")
    
            if val.startswith("yuan"):
                return val
            else:
                raise ValidationError("没有yuan开头")
    复制代码

    代码

     views.py

    from django.shortcuts import render,HttpResponse

    # Create your views here.

    from django import forms
    from django.forms import widgets
    from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
    class LoginForm(forms.Form):
    user=forms.CharField(label="用户名",min_length=3,max_length=8,
    widget=widgets.TextInput(attrs={"class": "form-control"}),
    error_messages={"min_length":"太短","required":"必填"})

    pwd=forms.CharField(label="密码",min_length=5,
    widget=widgets.PasswordInput(attrs={"class":"form-control"}),
    error_messages={"min_length":"太短", "required": "必填"}
    )

    def clean_user(self):
    val=self.cleaned_data.get("user")

    import re
    # if not UserInfo.objects.filter(username=val):
    # return val
    # else:
    # raise ValidationError("")

    if not val.isdigit():
    return val
    else:
    raise ValidationError("用户名不能是纯数字!")

    def clean_pwd(self):
    val=self.cleaned_data.get("pwd")

    if val.startswith("yuan"):
    return val
    else:
    raise ValidationError("没有yuan开头")

    # email=forms.EmailField()
    # age=forms.IntegerField()


    def login(request):
    if request.method=="POST":

    login_form=LoginForm(request.POST)
    if login_form.is_valid():
    print(login_form.cleaned_data) # {"user":"","pwd":123}
    return HttpResponse("OK")
    else:
    # print(login_form.cleaned_data)# {"pwd":123456}
    # print(type(login_form.errors)) # {"user":["","",]}
    # print(type(login_form.errors.get("user"))) # {"user":"....."}
    return render(request, "login_form.html", locals())

    login_form=LoginForm()
    return render(request,"login_form.html",locals())

    views.py

     login_form.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
    integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    </head>
    <body>


    {#<form action="" method="post" novalidate>#}
    {# {% csrf_token %}#}
    {# {{ login_form.as_p }}#}
    {# <input type="submit">#}
    {#</form>#}

    <hr>

    <div class="container">
    <div class="row">
    <div class="col-md-5">
    <form action="" method="post" novalidate>
    {% csrf_token %}
    <div class="form-group">
    <label for="">{{ login_form.user.label }}</label>
    {{ login_form.user }} <span>{{ login_form.errors.user.0 }}</span>
    </div>
    <div class="form-group">
    <label for="">{{ login_form.pwd.label }}</label>
    {{ login_form.pwd }} <span>{{ login_form.errors.pwd.0 }}</span>
    </div>
    <input type="submit">
    </form>
    </div>
    </div>
    </div>


    </body>
    </html>

    login_form.html

  • 相关阅读:
    PostgreSQL数据库管理:定期vacuum
    关于压力测试的思路
    作业自动提示功能设计思路
    This system is not registered with RHN
    读《高性能建站指南》(上)
    Ubuntu下PostgreSQL数据库集群(PL/Proxy)配置方法
    PG SQL数据库读写分离的思路
    ASP.NET知识点的明晰(非原创,东拼西凑的,向这些内容的原创者致敬)
    [转]Effective C#原则4:用条件属性而不是#if
    如何在Word文档中插入一条分隔线?
  • 原文地址:https://www.cnblogs.com/xyhh/p/10860262.html
Copyright © 2011-2022 走看看