| <!DOCTYPE html> | |
| <html lang="zh-cn"> | |
| <head> | |
| <meta charset="utf-8"/> | |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
| <meta name="referrer" content="origin" /> | |
| <title>Django Form和ModelForm组件 - Q1mi - 博客园</title> | |
| <meta property="og:description" content="Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来。 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否" /> | |
| <link type="text/css" rel="stylesheet" href="/bundles/blog-common.css?v=-duj5vpGTntb85GJoM3iRI972XwWcI-j8zmqDzyfu2w1"/> | |
| <link /> | |
| <link type="text/css" rel="stylesheet" href="/blog/customcss/260599.css?v=onf6r%2feJ3O3eaiWY9gfxVD5ElDg%3d"/> | |
| <link /> | |
| <link title="RSS" type="application/rss+xml" rel="alternate" href="https://www.cnblogs.com/liwenzhou/rss"/> | |
| <link title="RSD" type="application/rsd+xml" rel="EditURI" href="https://www.cnblogs.com/liwenzhou/rsd.xml"/> | |
| <link type="application/wlwmanifest+xml" rel="wlwmanifest" href="https://www.cnblogs.com/liwenzhou/wlwmanifest.xml"/> | |
| <script src="//common.cnblogs.com/scripts/jquery-2.2.0.min.js"></script> | |
| <script type="text/javascript">var currentBlogApp = 'liwenzhou', cb_enable_mathjax=false;var isLogined=false;</script> | |
| <script src="/bundles/blog-common.js?v=_U8OpbfIPk4K3Mxrx3oPrbJt2JRnf47OVRruaRlQuEc1" type="text/javascript"></script> | |
| </head> | |
| <body> | |
| <a name="top"></a> | |
| <!--PageBeginHtml Block Begin--> | |
| <link type="text/css" rel="stylesheet" href="https://blog-static.cnblogs.com/files/liwenzhou/myblog.css"> | |
| <!--PageBeginHtml Block End--> | |
| <!--done--> | |
| <div > | |
| <div > | |
| <div > | |
| <a ></a> | |
| <!--done--> | |
| <h1><a ></h1> | |
| <h2></h2> | |
| </div><!--end: blogTitle 博客的标题和副标题 --> | |
| <div > | |
| <ul > | |
| <li><a ></li> | |
| <li><a ></li> | |
| <li><a ></li> | |
| <li><a ></li> | |
| <li><a ></a> | |
| <!--<a ></li> | |
| <li><a ></li> | |
| </ul> | |
| <div class="blogStats"> | |
| <div > | |
| <span ></span> | |
| <span ></span> | |
| <span ></span> | |
| </div> | |
| </div><!--end: blogStats --> | |
| </div><!--end: navigator 博客导航栏 --> | |
| </div><!--end: header 头部 --> | |
| <div > | |
| <div > | |
| <div class="forFlow"> | |
| <div > | |
| <!--done--> | |
| <div > | |
| <div class = "post"> | |
| <h1 class = "postTitle"> | |
| <a ></a> | |
| </h1> | |
| <div class="clear"></div> | |
| <div class="postBody"> | |
| <div ></h1> | |
| <p>我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来。</p> | |
| <p>与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确。如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.。</p> | |
| <p>Django form组件就实现了上面所述的功能。</p> | |
| <p>总结一下,其实form组件的主要功能如下:</p> | |
| <ul> | |
| <li>生成页面可用的HTML标签</li> | |
| <li>对用户提交的数据进行校验</li> | |
| <li>保留上次输入内容</li> | |
| </ul> | |
| <h2>普通方式手写注册功能</h2> | |
| <h3>views.py</h3> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #008000;">#</span><span style="color: #008000;"> 注册</span> | |
| <span style="color: #0000ff;">def</span><span style="color: #000000;"> register(request): | |
| error_msg </span>= <span style="color: #800000;">""</span> | |
| <span style="color: #0000ff;">if</span> request.method == <span style="color: #800000;">"</span><span style="color: #800000;">POST</span><span style="color: #800000;">"</span><span style="color: #000000;">: | |
| username </span>= request.POST.get(<span style="color: #800000;">"</span><span style="color: #800000;">name</span><span style="color: #800000;">"</span><span style="color: #000000;">) | |
| pwd </span>= request.POST.get(<span style="color: #800000;">"</span><span style="color: #800000;">pwd</span><span style="color: #800000;">"</span><span style="color: #000000;">) | |
| </span><span style="color: #008000;">#</span><span style="color: #008000;"> 对注册信息做校验</span> | |
| <span style="color: #0000ff;">if</span> len(username) < 6<span style="color: #000000;">: | |
| </span><span style="color: #008000;">#</span><span style="color: #008000;"> 用户长度小于6位</span> | |
| error_msg = <span style="color: #800000;">"</span><span style="color: #800000;">用户名长度不能小于6位</span><span style="color: #800000;">"</span> | |
| <span style="color: #0000ff;">else</span><span style="color: #000000;">: | |
| </span><span style="color: #008000;">#</span><span style="color: #008000;"> 将用户名和密码存到数据库</span> | |
| <span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">"</span><span style="color: #800000;">注册成功</span><span style="color: #800000;">"</span><span style="color: #000000;">) | |
| </span><span style="color: #0000ff;">return</span> render(request, <span style="color: #800000;">"</span><span style="color: #800000;">register.html</span><span style="color: #800000;">"</span>, {<span style="color: #800000;">"</span><span style="color: #800000;">error_msg</span><span style="color: #800000;">"</span>: error_msg})</pre> | |
| </div> | |
| <h3>login.html</h3> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;"><!</span><span style="color: #ff00ff;">DOCTYPE html</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">html </span><span style="color: #ff0000;">lang</span><span style="color: #0000ff;">="en"</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">head</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">meta </span><span style="color: #ff0000;">charset</span><span style="color: #0000ff;">="UTF-8"</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">title</span><span style="color: #0000ff;">></span>注册页面<span style="color: #0000ff;"></</span><span style="color: #800000;">title</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"></</span><span style="color: #800000;">head</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">body</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">form </span><span style="color: #ff0000;">action</span><span style="color: #0000ff;">="/reg/"</span><span style="color: #ff0000;"> method</span><span style="color: #0000ff;">="post"</span><span style="color: #0000ff;">></span><span style="color: #000000;"> | |
| {% csrf_token %} | |
| </span><span style="color: #0000ff;"><</span><span style="color: #800000;">p</span><span style="color: #0000ff;">></span><span style="color: #000000;"> | |
| 用户名: | |
| </span><span style="color: #0000ff;"><</span><span style="color: #800000;">input </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="text"</span><span style="color: #ff0000;"> name</span><span style="color: #0000ff;">="name"</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"></</span><span style="color: #800000;">p</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">p</span><span style="color: #0000ff;">></span><span style="color: #000000;"> | |
| 密码: | |
| </span><span style="color: #0000ff;"><</span><span style="color: #800000;">input </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="password"</span><span style="color: #ff0000;"> name</span><span style="color: #0000ff;">="pwd"</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"></</span><span style="color: #800000;">p</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">p</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">input </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="submit"</span><span style="color: #ff0000;"> value</span><span style="color: #0000ff;">="注册"</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">p </span><span style="color: #ff0000;">style</span><span style="color: #0000ff;">="color: red"</span><span style="color: #0000ff;">></span>{{ error_msg }}<span style="color: #0000ff;"></</span><span style="color: #800000;">p</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"></</span><span style="color: #800000;">p</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"></</span><span style="color: #800000;">form</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"></</span><span style="color: #800000;">body</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"></</span><span style="color: #800000;">html</span><span style="color: #0000ff;">></span></pre> | |
| </div> | |
| <h2>使用form组件实现注册功能</h2> | |
| <h3>views.py</h3> | |
| <p>先定义好一个RegForm类:</p> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;">from</span> django <span style="color: #0000ff;">import</span><span style="color: #000000;"> forms | |
| </span><span style="color: #008000;">#</span><span style="color: #008000;"> 按照Django form组件的要求自己写一个类</span> | |
| <span style="color: #0000ff;">class</span><span style="color: #000000;"> RegForm(forms.Form): | |
| name </span>= forms.CharField(label=<span style="color: #800000;">"</span><span style="color: #800000;">用户名</span><span style="color: #800000;">"</span><span style="color: #000000;">) | |
| pwd </span>= forms.CharField(label=<span style="color: #800000;">"</span><span style="color: #800000;">密码</span><span style="color: #800000;">"</span>)</pre> | |
| </div> | |
| <p>再写一个视图函数:</p> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #008000;">#</span><span style="color: #008000;"> 使用form组件实现注册方式</span> | |
| <span style="color: #0000ff;">def</span><span style="color: #000000;"> register2(request): | |
| form_obj </span>=<span style="color: #000000;"> RegForm() | |
| </span><span style="color: #0000ff;">if</span> request.method == <span style="color: #800000;">"</span><span style="color: #800000;">POST</span><span style="color: #800000;">"</span><span style="color: #000000;">: | |
| </span><span style="color: #008000;">#</span><span style="color: #008000;"> 实例化form对象的时候,把post提交过来的数据直接传进去</span> | |
| form_obj =<span style="color: #000000;"> RegForm(request.POST) | |
| </span><span style="color: #008000;">#</span><span style="color: #008000;"> 调用form_obj校验数据的方法</span> | |
| <span style="color: #0000ff;">if</span><span style="color: #000000;"> form_obj.is_valid(): | |
| </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">"</span><span style="color: #800000;">注册成功</span><span style="color: #800000;">"</span><span style="color: #000000;">) | |
| </span><span style="color: #0000ff;">return</span> render(request, <span style="color: #800000;">"</span><span style="color: #800000;">register2.html</span><span style="color: #800000;">"</span>, {<span style="color: #800000;">"</span><span style="color: #800000;">form_obj</span><span style="color: #800000;">"</span>: form_obj})</pre> | |
| </div> | |
| <h3>login2.html</h3> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;"><!</span><span style="color: #ff00ff;">DOCTYPE html</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">html </span><span style="color: #ff0000;">lang</span><span style="color: #0000ff;">="en"</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">head</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">meta </span><span style="color: #ff0000;">charset</span><span style="color: #0000ff;">="UTF-8"</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">title</span><span style="color: #0000ff;">></span>注册2<span style="color: #0000ff;"></</span><span style="color: #800000;">title</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"></</span><span style="color: #800000;">head</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">body</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">form </span><span style="color: #ff0000;">action</span><span style="color: #0000ff;">="/reg2/"</span><span style="color: #ff0000;"> method</span><span style="color: #0000ff;">="post"</span><span style="color: #ff0000;"> novalidate autocomplete</span><span style="color: #0000ff;">="off"</span><span style="color: #0000ff;">></span><span style="color: #000000;"> | |
| {% csrf_token %} | |
| </span><span style="color: #0000ff;"><</span><span style="color: #800000;">div</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">label </span><span style="color: #ff0000;">for</span><span style="color: #0000ff;">="{{ form_obj.name.id_for_label }}"</span><span style="color: #0000ff;">></span>{{ form_obj.name.label }}<span style="color: #0000ff;"></</span><span style="color: #800000;">label</span><span style="color: #0000ff;">></span><span style="color: #000000;"> | |
| {{ form_obj.name }} {{ form_obj.name.errors.0 }} | |
| </span><span style="color: #0000ff;"></</span><span style="color: #800000;">div</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">div</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">label </span><span style="color: #ff0000;">for</span><span style="color: #0000ff;">="{{ form_obj.pwd.id_for_label }}"</span><span style="color: #0000ff;">></span>{{ form_obj.pwd.label }}<span style="color: #0000ff;"></</span><span style="color: #800000;">label</span><span style="color: #0000ff;">></span><span style="color: #000000;"> | |
| {{ form_obj.pwd }} {{ form_obj.pwd.errors.0 }} | |
| </span><span style="color: #0000ff;"></</span><span style="color: #800000;">div</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">div</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"><</span><span style="color: #800000;">input </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="submit"</span><span style="color: #ff0000;"> class</span><span style="color: #0000ff;">="btn btn-success"</span><span style="color: #ff0000;"> value</span><span style="color: #0000ff;">="注册"</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"></</span><span style="color: #800000;">div</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"></</span><span style="color: #800000;">form</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"></</span><span style="color: #800000;">body</span><span style="color: #0000ff;">></span> | |
| <span style="color: #0000ff;"></</span><span style="color: #800000;">html</span><span style="color: #0000ff;">></span></pre> | |
| </div> | |
| <p> </p> | |
| <p>看网页效果发现 也验证了form的功能:<br />• 前端页面是form类的对象生成的 -->生成HTML标签功能<br />• 当用户名和密码输入为空或输错之后 页面都会提示 -->用户提交校验功能<br />• 当用户输错之后 再次输入 上次的内容还保留在input框 -->保留上次输入内容</p> | |
| <h1>Form那些事儿</h1> | |
| <h2>常用字段与插件</h2> | |
| <p>创建Form类时,主要涉及到 【字段】 和 【插件】,字段用于对用户请求数据的验证,插件用于自动生成HTML;</p> | |
| <h3>initial</h3> | |
| <p>初始值,input框里面的初始值。</p> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;">class</span><span style="color: #000000;"> LoginForm(forms.Form): | |
| username </span>=<span style="color: #000000;"> forms.CharField( | |
| min_length</span>=8<span style="color: #000000;">, | |
| label</span>=<span style="color: #800000;">"</span><span style="color: #800000;">用户名</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| initial</span>=<span style="color: #800000;">"</span><span style="color: #800000;">张三</span><span style="color: #800000;">"</span> <span style="color: #008000;">#</span><span style="color: #008000;"> 设置默认值</span> | |
| <span style="color: #000000;"> ) | |
| pwd </span>= forms.CharField(min_length=6, label=<span style="color: #800000;">"</span><span style="color: #800000;">密码</span><span style="color: #800000;">"</span>)</pre> | |
| </div> | |
| <h3>error_messages</h3> | |
| <p>重写错误信息。</p> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;">class</span><span style="color: #000000;"> LoginForm(forms.Form): | |
| username </span>=<span style="color: #000000;"> forms.CharField( | |
| min_length</span>=8<span style="color: #000000;">, | |
| label</span>=<span style="color: #800000;">"</span><span style="color: #800000;">用户名</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| initial</span>=<span style="color: #800000;">"</span><span style="color: #800000;">张三</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| error_messages</span>=<span style="color: #000000;">{ | |
| </span><span style="color: #800000;">"</span><span style="color: #800000;">required</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">不能为空</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| </span><span style="color: #800000;">"</span><span style="color: #800000;">invalid</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">格式错误</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| </span><span style="color: #800000;">"</span><span style="color: #800000;">min_length</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">用户名最短8位</span><span style="color: #800000;">"</span><span style="color: #000000;"> | |
| } | |
| ) | |
| pwd </span>= forms.CharField(min_length=6, label=<span style="color: #800000;">"</span><span style="color: #800000;">密码</span><span style="color: #800000;">"</span>)</pre> | |
| </div> | |
| <h3>password</h3> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;">class</span><span style="color: #000000;"> LoginForm(forms.Form): | |
| ... | |
| pwd </span>=<span style="color: #000000;"> forms.CharField( | |
| min_length</span>=6<span style="color: #000000;">, | |
| label</span>=<span style="color: #800000;">"</span><span style="color: #800000;">密码</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| widget</span>=forms.widgets.PasswordInput(attrs={<span style="color: #800000;">'</span><span style="color: #800000;">class</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">c1</span><span style="color: #800000;">'</span>}, render_value=<span style="color: #000000;">True) | |
| )</span></pre> | |
| </div> | |
| <h3>radioSelect</h3> | |
| <p>单radio值为字符串</p> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;">class</span><span style="color: #000000;"> LoginForm(forms.Form): | |
| username </span>=<span style="color: #000000;"> forms.CharField( | |
| min_length</span>=8<span style="color: #000000;">, | |
| label</span>=<span style="color: #800000;">"</span><span style="color: #800000;">用户名</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| initial</span>=<span style="color: #800000;">"</span><span style="color: #800000;">张三</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| error_messages</span>=<span style="color: #000000;">{ | |
| </span><span style="color: #800000;">"</span><span style="color: #800000;">required</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">不能为空</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| </span><span style="color: #800000;">"</span><span style="color: #800000;">invalid</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">格式错误</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| </span><span style="color: #800000;">"</span><span style="color: #800000;">min_length</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">用户名最短8位</span><span style="color: #800000;">"</span><span style="color: #000000;"> | |
| } | |
| ) | |
| pwd </span>= forms.CharField(min_length=6, label=<span style="color: #800000;">"</span><span style="color: #800000;">密码</span><span style="color: #800000;">"</span><span style="color: #000000;">) | |
| gender </span>=<span style="color: #000000;"> forms.fields.ChoiceField( | |
| choices</span>=((1, <span style="color: #800000;">"</span><span style="color: #800000;">男</span><span style="color: #800000;">"</span>), (2, <span style="color: #800000;">"</span><span style="color: #800000;">女</span><span style="color: #800000;">"</span>), (3, <span style="color: #800000;">"</span><span style="color: #800000;">保密</span><span style="color: #800000;">"</span><span style="color: #000000;">)), | |
| label</span>=<span style="color: #800000;">"</span><span style="color: #800000;">性别</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| initial</span>=3<span style="color: #000000;">, | |
| widget</span>=<span style="color: #000000;">forms.widgets.RadioSelect() | |
| )</span></pre> | |
| </div> | |
| <h3>单选Select</h3> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;">class</span><span style="color: #000000;"> LoginForm(forms.Form): | |
| ... | |
| hobby </span>=<span style="color: #000000;"> forms.fields.ChoiceField( | |
| choices</span>=((1, <span style="color: #800000;">"</span><span style="color: #800000;">篮球</span><span style="color: #800000;">"</span>), (2, <span style="color: #800000;">"</span><span style="color: #800000;">足球</span><span style="color: #800000;">"</span>), (3, <span style="color: #800000;">"</span><span style="color: #800000;">双色球</span><span style="color: #800000;">"</span><span style="color: #000000;">), ), | |
| label</span>=<span style="color: #800000;">"</span><span style="color: #800000;">爱好</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| initial</span>=3<span style="color: #000000;">, | |
| widget</span>=<span style="color: #000000;">forms.widgets.Select() | |
| )</span></pre> | |
| </div> | |
| <h3>多选Select</h3> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;">class</span><span style="color: #000000;"> LoginForm(forms.Form): | |
| ... | |
| hobby </span>=<span style="color: #000000;"> forms.fields.MultipleChoiceField( | |
| choices</span>=((1, <span style="color: #800000;">"</span><span style="color: #800000;">篮球</span><span style="color: #800000;">"</span>), (2, <span style="color: #800000;">"</span><span style="color: #800000;">足球</span><span style="color: #800000;">"</span>), (3, <span style="color: #800000;">"</span><span style="color: #800000;">双色球</span><span style="color: #800000;">"</span><span style="color: #000000;">), ), | |
| label</span>=<span style="color: #800000;">"</span><span style="color: #800000;">爱好</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| initial</span>=[1, 3<span style="color: #000000;">], | |
| widget</span>=<span style="color: #000000;">forms.widgets.SelectMultiple() | |
| )</span></pre> | |
| </div> | |
| <h3>单选checkbox</h3> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;">class</span><span style="color: #000000;"> LoginForm(forms.Form): | |
| ... | |
| keep </span>=<span style="color: #000000;"> forms.fields.ChoiceField( | |
| label</span>=<span style="color: #800000;">"</span><span style="color: #800000;">是否记住密码</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| initial</span>=<span style="color: #800000;">"</span><span style="color: #800000;">checked</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| widget</span>=<span style="color: #000000;">forms.widgets.CheckboxInput() | |
| )</span></pre> | |
| </div> | |
| <h3>多选checkbox</h3> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;">class</span><span style="color: #000000;"> LoginForm(forms.Form): | |
| ... | |
| hobby </span>=<span style="color: #000000;"> forms.fields.MultipleChoiceField( | |
| choices</span>=((1, <span style="color: #800000;">"</span><span style="color: #800000;">篮球</span><span style="color: #800000;">"</span>), (2, <span style="color: #800000;">"</span><span style="color: #800000;">足球</span><span style="color: #800000;">"</span>), (3, <span style="color: #800000;">"</span><span style="color: #800000;">双色球</span><span style="color: #800000;">"</span><span style="color: #000000;">),), | |
| label</span>=<span style="color: #800000;">"</span><span style="color: #800000;">爱好</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| initial</span>=[1, 3<span style="color: #000000;">], | |
| widget</span>=<span style="color: #000000;">forms.widgets.CheckboxSelectMultiple() | |
| )</span></pre> | |
| </div> | |
| <h3>choice字段注意事项</h3> | |
| <p>在使用选择标签时,需要注意choices的选项可以配置从数据库中获取,但是由于是静态字段 <span style="background-color: #ffff00;">获取的值无法实时更新</span>,需要重写构造方法从而实现choice实时更新。</p> | |
| <p>方式一:</p> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;">from</span> django.forms <span style="color: #0000ff;">import</span><span style="color: #000000;"> Form | |
| </span><span style="color: #0000ff;">from</span> django.forms <span style="color: #0000ff;">import</span><span style="color: #000000;"> widgets | |
| </span><span style="color: #0000ff;">from</span> django.forms <span style="color: #0000ff;">import</span><span style="color: #000000;"> fields | |
| </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> MyForm(Form): | |
| user </span>=<span style="color: #000000;"> fields.ChoiceField( | |
| </span><span style="color: #008000;">#</span><span style="color: #008000;"> choices=((1, '上海'), (2, '北京'),),</span> | |
| initial=2<span style="color: #000000;">, | |
| widget</span>=<span style="color: #000000;">widgets.Select | |
| ) | |
| </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__init__</span>(self, *args, **<span style="color: #000000;">kwargs): | |
| super(MyForm,self).</span><span style="color: #800080;">__init__</span>(*args, **<span style="color: #000000;">kwargs) | |
| </span><span style="color: #008000;">#</span><span style="color: #008000;"> self.fields['user'].choices = ((1, '上海'), (2, '北京'),)</span> | |
| <span style="color: #008000;">#</span><span style="color: #008000;"> 或</span> | |
| self.fields[<span style="color: #800000;">'</span><span style="color: #800000;">user</span><span style="color: #800000;">'</span>].choices = models.Classes.objects.all().values_list(<span style="color: #800000;">'</span><span style="color: #800000;">id</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">caption</span><span style="color: #800000;">'</span>)</pre> | |
| </div> | |
| <p>方式二:</p> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;">from</span> django <span style="color: #0000ff;">import</span><span style="color: #000000;"> forms | |
| </span><span style="color: #0000ff;">from</span> django.forms <span style="color: #0000ff;">import</span><span style="color: #000000;"> fields | |
| </span><span style="color: #0000ff;">from</span> django.forms <span style="color: #0000ff;">import</span><span style="color: #000000;"> models as form_model | |
| </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> FInfo(forms.Form): | |
| authors </span>= form_model.ModelMultipleChoiceField(queryset=<span style="color: #000000;">models.NNewType.objects.all()) # 多选 | |
| </span><span style="color: #008000;">#</span><span style="color: #008000;"> authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all()) # 单选</span></pre> | |
| </div> | |
| <h2>Django Form所有内置字段</h2> | |
| <div class="likecs_code" onclick="likecs_code_show('334baf3a-bb4c-499a-965a-c8f421fefe89')"><img /> | |
| <div > | |
| <pre><span style="color: #000000;">Field | |
| required</span>=<span style="color: #000000;">True, 是否允许为空 | |
| widget</span>=<span style="color: #000000;">None, HTML插件 | |
| label</span>=<span style="color: #000000;">None, 用于生成Label标签或显示内容 | |
| initial</span>=<span style="color: #000000;">None, 初始值 | |
| help_text</span>=<span style="color: #800000;">''</span><span style="color: #000000;">, 帮助信息(在标签旁边显示) | |
| error_messages</span>=None, 错误信息 {<span style="color: #800000;">'</span><span style="color: #800000;">required</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">不能为空</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">invalid</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">格式错误</span><span style="color: #800000;">'</span><span style="color: #000000;">} | |
| validators</span>=<span style="color: #000000;">[], 自定义验证规则 | |
| localize</span>=<span style="color: #000000;">False, 是否支持本地化 | |
| disabled</span>=<span style="color: #000000;">False, 是否可以编辑 | |
| label_suffix</span>=<span style="color: #000000;">None Label内容后缀 | |
| CharField(Field) | |
| max_length</span>=<span style="color: #000000;">None, 最大长度 | |
| min_length</span>=<span style="color: #000000;">None, 最小长度 | |
| strip</span>=<span style="color: #000000;">True 是否移除用户输入空白 | |
| IntegerField(Field) | |
| max_value</span>=<span style="color: #000000;">None, 最大值 | |
| min_value</span>=<span style="color: #000000;">None, 最小值 | |
| FloatField(IntegerField) | |
| ... | |
| DecimalField(IntegerField) | |
| max_value</span>=<span style="color: #000000;">None, 最大值 | |
| min_value</span>=<span style="color: #000000;">None, 最小值 | |
| max_digits</span>=<span style="color: #000000;">None, 总长度 | |
| decimal_places</span>=<span style="color: #000000;">None, 小数位长度 | |
| BaseTemporalField(Field) | |
| input_formats</span>=<span style="color: #000000;">None 时间格式化 | |
| DateField(BaseTemporalField) 格式:</span><span style="color: #800080;">2015</span>-<span style="color: #800080;">09</span>-<span style="color: #800080;">01</span><span style="color: #000000;"> | |
| TimeField(BaseTemporalField) 格式:</span><span style="color: #800080;">11</span>:<span style="color: #800080;">12</span><span style="color: #000000;"> | |
| DateTimeField(BaseTemporalField)格式:</span><span style="color: #800080;">2015</span>-<span style="color: #800080;">09</span>-<span style="color: #800080;">01</span> <span style="color: #800080;">11</span>:<span style="color: #800080;">12</span><span style="color: #000000;"> | |
| DurationField(Field) 时间间隔:</span>%d %H:%M:%S.%<span style="color: #000000;">f | |
| ... | |
| RegexField(CharField) | |
| regex, 自定制正则表达式 | |
| max_length</span>=<span style="color: #000000;">None, 最大长度 | |
| min_length</span>=<span style="color: #000000;">None, 最小长度 | |
| error_message</span>=None, 忽略,错误信息使用 error_messages={<span style="color: #800000;">'</span><span style="color: #800000;">invalid</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">...</span><span style="color: #800000;">'</span><span style="color: #000000;">} | |
| EmailField(CharField) | |
| ... | |
| FileField(Field) | |
| allow_empty_file</span>=<span style="color: #000000;">False 是否允许空文件 | |
| ImageField(FileField) | |
| ... | |
| 注:需要PIL模块,pip3 </span><span style="color: #0000ff;">install</span><span style="color: #000000;"> Pillow | |
| 以上两个字典使用时,需要注意两点: | |
| </span>- form表单中 enctype=<span style="color: #800000;">"</span><span style="color: #800000;">multipart/form-data</span><span style="color: #800000;">"</span> | |
| - view函数中 obj =<span style="color: #000000;"> MyForm(request.POST, request.FILES) | |
| URLField(Field) | |
| ... | |
| BooleanField(Field) | |
| ... | |
| NullBooleanField(BooleanField) | |
| ... | |
| ChoiceField(Field) | |
| ... | |
| choices</span>=(), 选项,如:choices = ((<span style="color: #800080;">0</span>,<span style="color: #800000;">'</span><span style="color: #800000;">上海</span><span style="color: #800000;">'</span>),(<span style="color: #800080;">1</span>,<span style="color: #800000;">'</span><span style="color: #800000;">北京</span><span style="color: #800000;">'</span><span style="color: #000000;">),) | |
| required</span>=<span style="color: #000000;">True, 是否必填 | |
| widget</span>=<span style="color: #000000;">None, 插件,默认select插件 | |
| label</span>=<span style="color: #000000;">None, Label内容 | |
| initial</span>=<span style="color: #000000;">None, 初始值 | |
| help_text</span>=<span style="color: #800000;">''</span><span style="color: #000000;">, 帮助提示 | |
| ModelChoiceField(ChoiceField) | |
| ... django.forms.models.ModelChoiceField | |
| queryset, # 查询数据库中的数据 | |
| empty_label</span>=<span style="color: #800000;">"</span><span style="color: #800000;">---------</span><span style="color: #800000;">"</span><span style="color: #000000;">, # 默认空显示内容 | |
| to_field_name</span>=<span style="color: #000000;">None, # HTML中value的值对应的字段 | |
| limit_choices_to</span>=<span style="color: #000000;">None # ModelForm中对queryset二次筛选 | |
| ModelMultipleChoiceField(ModelChoiceField) | |
| ... django.forms.models.ModelMultipleChoiceField | |
| TypedChoiceField(ChoiceField) | |
| coerce </span>=<span style="color: #000000;"> lambda val: val 对选中的值进行一次转换 | |
| empty_value</span>= <span style="color: #800000;">''</span><span style="color: #000000;"> 空值的默认值 | |
| MultipleChoiceField(ChoiceField) | |
| ... | |
| TypedMultipleChoiceField(MultipleChoiceField) | |
| coerce </span>=<span style="color: #000000;"> lambda val: val 对选中的每一个值进行一次转换 | |
| empty_value</span>= <span style="color: #800000;">''</span><span style="color: #000000;"> 空值的默认值 | |
| ComboField(Field) | |
| fields</span>=<span style="color: #000000;">() 使用多个验证,如下:即验证最大长度20,又验证邮箱格式 | |
| fields.ComboField(fields</span>=[fields.CharField(max_length=<span style="color: #800080;">20</span><span style="color: #000000;">), fields.EmailField(),]) | |
| MultiValueField(Field) | |
| PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用 | |
| SplitDateTimeField(MultiValueField) | |
| input_date_formats</span>=None, 格式列表:[<span style="color: #800000;">'</span><span style="color: #800000;">%Y--%m--%d</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">%m%d/%Y</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">%m/%d/%y</span><span style="color: #800000;">'</span><span style="color: #000000;">] | |
| input_time_formats</span>=None 格式列表:[<span style="color: #800000;">'</span><span style="color: #800000;">%H:%M:%S</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">%H:%M:%S.%f</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">%H:%M</span><span style="color: #800000;">'</span><span style="color: #000000;">] | |
| FilePathField(ChoiceField) 文件选项,目录下文件显示在页面中 | |
| path, 文件夹路径 | |
| match</span>=<span style="color: #000000;">None, 正则匹配 | |
| recursive</span>=<span style="color: #000000;">False, 递归下面的文件夹 | |
| allow_files</span>=<span style="color: #000000;">True, 允许文件 | |
| allow_folders</span>=<span style="color: #000000;">False, 允许文件夹 | |
| required</span>=<span style="color: #000000;">True, | |
| widget</span>=<span style="color: #000000;">None, | |
| label</span>=<span style="color: #000000;">None, | |
| initial</span>=<span style="color: #000000;">None, | |
| help_text</span>=<span style="color: #800000;">''</span><span style="color: #000000;"> | |
| GenericIPAddressField | |
| protocol</span>=<span style="color: #800000;">'</span><span style="color: #800000;">both</span><span style="color: #800000;">'</span><span style="color: #000000;">, both,ipv4,ipv6支持的IP格式 | |
| unpack_ipv4</span>=False 解析ipv4地址,如果是::ffff:<span style="color: #800080;">192.0</span>.<span style="color: #800080;">2</span>.1时候,可解析为192.<span style="color: #800080;">0.2</span>.<span style="color: #800080;">1</span><span style="color: #000000;">, PS:protocol必须为both才能启用 | |
| SlugField(CharField) 数字,字母,下划线,减号(连字符) | |
| ... | |
| UUIDField(CharField) uuid类型</span></pre> | |
| </div> | |
| <span class="likecs_code_collapse">Django Form内置字段</span></div> | |
| <h2>字段校验</h2> | |
| <h3>RegexValidator验证器</h3> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;">from</span> django.forms <span style="color: #0000ff;">import</span><span style="color: #000000;"> Form | |
| </span><span style="color: #0000ff;">from</span> django.forms <span style="color: #0000ff;">import</span><span style="color: #000000;"> widgets | |
| </span><span style="color: #0000ff;">from</span> django.forms <span style="color: #0000ff;">import</span><span style="color: #000000;"> fields | |
| </span><span style="color: #0000ff;">from</span> django.core.validators <span style="color: #0000ff;">import</span><span style="color: #000000;"> RegexValidator | |
| </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> MyForm(Form): | |
| user </span>=<span style="color: #000000;"> fields.CharField( | |
| validators</span>=[RegexValidator(r<span style="color: #800000;">'</span><span style="color: #800000;">^[0-9]+$</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">请输入数字</span><span style="color: #800000;">'</span>), RegexValidator(r<span style="color: #800000;">'</span><span style="color: #800000;">^159[0-9]+$</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">数字必须以159开头</span><span style="color: #800000;">'</span><span style="color: #000000;">)], | |
| )</span></pre> | |
| </div> | |
| <h3>自定义验证函数</h3> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;">import</span><span style="color: #000000;"> re | |
| </span><span style="color: #0000ff;">from</span> django.forms <span style="color: #0000ff;">import</span><span style="color: #000000;"> Form | |
| </span><span style="color: #0000ff;">from</span> django.forms <span style="color: #0000ff;">import</span><span style="color: #000000;"> widgets | |
| </span><span style="color: #0000ff;">from</span> django.forms <span style="color: #0000ff;">import</span><span style="color: #000000;"> fields | |
| </span><span style="color: #0000ff;">from</span> django.core.exceptions <span style="color: #0000ff;">import</span><span style="color: #000000;"> ValidationError | |
| </span><span style="color: #008000;">#</span><span style="color: #008000;"> 自定义验证规则</span> | |
| <span style="color: #0000ff;">def</span><span style="color: #000000;"> mobile_validate(value): | |
| mobile_re </span>= re.compile(r<span style="color: #800000;">'</span><span style="color: #800000;">^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$</span><span style="color: #800000;">'</span><span style="color: #000000;">) | |
| </span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> mobile_re.match(value): | |
| </span><span style="color: #0000ff;">raise</span> ValidationError(<span style="color: #800000;">'</span><span style="color: #800000;">手机号码格式错误</span><span style="color: #800000;">'</span><span style="color: #000000;">) | |
| </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> PublishForm(Form): | |
| title </span>= fields.CharField(max_length=20<span style="color: #000000;">, | |
| min_length</span>=5<span style="color: #000000;">, | |
| error_messages</span>={<span style="color: #800000;">'</span><span style="color: #800000;">required</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">标题不能为空</span><span style="color: #800000;">'</span><span style="color: #000000;">, | |
| </span><span style="color: #800000;">'</span><span style="color: #800000;">min_length</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">标题最少为5个字符</span><span style="color: #800000;">'</span><span style="color: #000000;">, | |
| </span><span style="color: #800000;">'</span><span style="color: #800000;">max_length</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">标题最多为20个字符</span><span style="color: #800000;">'</span><span style="color: #000000;">}, | |
| widget</span>=widgets.TextInput(attrs={<span style="color: #800000;">'</span><span style="color: #800000;">class</span><span style="color: #800000;">'</span>: <span style="color: #800000;">"</span><span style="color: #800000;">form-control</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| </span><span style="color: #800000;">'</span><span style="color: #800000;">placeholder</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">标题5-20个字符</span><span style="color: #800000;">'</span><span style="color: #000000;">})) | |
| </span><span style="color: #008000;">#</span><span style="color: #008000;"> 使用自定义验证规则</span> | |
| phone = fields.CharField(validators=<span style="color: #000000;">[mobile_validate, ], | |
| error_messages</span>={<span style="color: #800000;">'</span><span style="color: #800000;">required</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">手机不能为空</span><span style="color: #800000;">'</span><span style="color: #000000;">}, | |
| widget</span>=widgets.TextInput(attrs={<span style="color: #800000;">'</span><span style="color: #800000;">class</span><span style="color: #800000;">'</span>: <span style="color: #800000;">"</span><span style="color: #800000;">form-control</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| </span><span style="color: #800000;">'</span><span style="color: #800000;">placeholder</span><span style="color: #800000;">'</span>: u<span style="color: #800000;">'</span><span style="color: #800000;">手机号码</span><span style="color: #800000;">'</span><span style="color: #000000;">})) | |
| email </span>= fields.EmailField(required=<span style="color: #000000;">False, | |
| error_messages</span>={<span style="color: #800000;">'</span><span style="color: #800000;">required</span><span style="color: #800000;">'</span>: u<span style="color: #800000;">'</span><span style="color: #800000;">邮箱不能为空</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">invalid</span><span style="color: #800000;">'</span>: u<span style="color: #800000;">'</span><span style="color: #800000;">邮箱格式错误</span><span style="color: #800000;">'</span><span style="color: #000000;">}, | |
| widget</span>=widgets.TextInput(attrs={<span style="color: #800000;">'</span><span style="color: #800000;">class</span><span style="color: #800000;">'</span>: <span style="color: #800000;">"</span><span style="color: #800000;">form-control</span><span style="color: #800000;">"</span>, <span style="color: #800000;">'</span><span style="color: #800000;">placeholder</span><span style="color: #800000;">'</span>: u<span style="color: #800000;">'</span><span style="color: #800000;">邮箱</span><span style="color: #800000;">'</span>}))</pre> | |
| </div> | |
| <h2>Hook方法</h2> | |
| <p>除了上面两种方式,我们还可以在Form类中定义钩子函数,来实现自定义的验证功能。</p> | |
| <h3>局部钩子</h3> | |
| <p>我们在Fom类中定义 clean_字段名() 方法,就能够实现对特定字段进行校验。</p> | |
| <p>举个例子:</p> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;">class</span><span style="color: #000000;"> LoginForm(forms.Form): | |
| username </span>=<span style="color: #000000;"> forms.CharField( | |
| min_length</span>=8<span style="color: #000000;">, | |
| label</span>=<span style="color: #800000;">"</span><span style="color: #800000;">用户名</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| initial</span>=<span style="color: #800000;">"</span><span style="color: #800000;">张三</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| error_messages</span>=<span style="color: #000000;">{ | |
| </span><span style="color: #800000;">"</span><span style="color: #800000;">required</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">不能为空</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| </span><span style="color: #800000;">"</span><span style="color: #800000;">invalid</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">格式错误</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| </span><span style="color: #800000;">"</span><span style="color: #800000;">min_length</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">用户名最短8位</span><span style="color: #800000;">"</span><span style="color: #000000;"> | |
| }, | |
| widget</span>=forms.widgets.TextInput(attrs={<span style="color: #800000;">"</span><span style="color: #800000;">class</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">form-control</span><span style="color: #800000;">"</span><span style="color: #000000;">}) | |
| ) | |
| ... | |
| </span><span style="color: #008000;">#</span><span style="color: #008000;"> 定义局部钩子,用来校验username字段</span> | |
| <span style="color: #0000ff;">def</span><span style="color: #000000;"> clean_username(self): | |
| value </span>= self.cleaned_data.get(<span style="color: #800000;">"</span><span style="color: #800000;">username</span><span style="color: #800000;">"</span><span style="color: #000000;">) | |
| </span><span style="color: #0000ff;">if</span> <span style="color: #800000;">"</span><span style="color: #800000;">666</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">in</span><span style="color: #000000;"> value: | |
| </span><span style="color: #0000ff;">raise</span> ValidationError(<span style="color: #800000;">"</span><span style="color: #800000;">光喊666是不行的</span><span style="color: #800000;">"</span><span style="color: #000000;">) | |
| </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: | |
| </span><span style="color: #0000ff;">return</span> value</pre> | |
| </div> | |
| <h3>全局钩子</h3> | |
| <p>我们在Fom类中定义 clean() 方法,就能够实现对字段进行全局校验。</p> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;">class</span><span style="color: #000000;"> LoginForm(forms.Form): | |
| ... | |
| password </span>=<span style="color: #000000;"> forms.CharField( | |
| min_length</span>=6<span style="color: #000000;">, | |
| label</span>=<span style="color: #800000;">"</span><span style="color: #800000;">密码</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| widget</span>=forms.widgets.PasswordInput(attrs={<span style="color: #800000;">'</span><span style="color: #800000;">class</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">form-control</span><span style="color: #800000;">'</span>}, render_value=<span style="color: #000000;">True) | |
| ) | |
| re_password </span>=<span style="color: #000000;"> forms.CharField( | |
| min_length</span>=6<span style="color: #000000;">, | |
| label</span>=<span style="color: #800000;">"</span><span style="color: #800000;">确认密码</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| widget</span>=forms.widgets.PasswordInput(attrs={<span style="color: #800000;">'</span><span style="color: #800000;">class</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">form-control</span><span style="color: #800000;">'</span>}, render_value=<span style="color: #000000;">True) | |
| ) | |
| ... | |
| </span><span style="color: #008000;">#</span><span style="color: #008000;"> 定义全局的钩子,用来校验密码和确认密码字段是否相同</span> | |
| <span style="color: #0000ff;">def</span><span style="color: #000000;"> clean(self): | |
| password_value </span>= self.cleaned_data.get(<span style="color: #800000;">'</span><span style="color: #800000;">password</span><span style="color: #800000;">'</span><span style="color: #000000;">) | |
| re_password_value </span>= self.cleaned_data.get(<span style="color: #800000;">'</span><span style="color: #800000;">re_password</span><span style="color: #800000;">'</span><span style="color: #000000;">) | |
| </span><span style="color: #0000ff;">if</span> password_value ==<span style="color: #000000;"> re_password_value: | |
| </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> self.cleaned_data | |
| </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: | |
| self.add_error(</span><span style="color: #800000;">'</span><span style="color: #800000;">re_password</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">两次密码不一致</span><span style="color: #800000;">'</span><span style="color: #000000;">) | |
| </span><span style="color: #0000ff;">raise</span> ValidationError(<span style="color: #800000;">'</span><span style="color: #800000;">两次密码不一致</span><span style="color: #800000;">'</span>)</pre> | |
| </div> | |
| <p> </p> | |
| <h2>补充进阶</h2> | |
| <h3>应用Bootstrap样式</h3> | |
| <div class="likecs_code" onclick="likecs_code_show('ba025422-27f5-4fa9-aa19-8855bb8e8041')"><img /> | |
| <div > | |
| <pre><!DOCTYPE html> | |
| <html lang=<span style="color: #800000;">"</span><span style="color: #800000;">en</span><span style="color: #800000;">"</span>> | |
| <head> | |
| <meta charset=<span style="color: #800000;">"</span><span style="color: #800000;">UTF-8</span><span style="color: #800000;">"</span>> | |
| <meta http-equiv=<span style="color: #800000;">"</span><span style="color: #800000;">x-ua-compatible</span><span style="color: #800000;">"</span> content=<span style="color: #800000;">"</span><span style="color: #800000;">IE=edge</span><span style="color: #800000;">"</span>> | |
| <meta name=<span style="color: #800000;">"</span><span style="color: #800000;">viewport</span><span style="color: #800000;">"</span> content=<span style="color: #800000;">"</span><span style="color: #800000;">width=device-width, initial-scale=1</span><span style="color: #800000;">"</span>> | |
| <link rel=<span style="color: #800000;">"</span><span style="color: #800000;">stylesheet</span><span style="color: #800000;">"</span> href=<span style="color: #800000;">"</span><span style="color: #800000;">/static/bootstrap/css/bootstrap.min.css</span><span style="color: #800000;">"</span>> | |
| <title>login</title> | |
| </head> | |
| <body> | |
| <div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">container</span><span style="color: #800000;">"</span>> | |
| <div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">row</span><span style="color: #800000;">"</span>> | |
| <form action=<span style="color: #800000;">"</span><span style="color: #800000;">/login2/</span><span style="color: #800000;">"</span> method=<span style="color: #800000;">"</span><span style="color: #800000;">post</span><span style="color: #800000;">"</span> novalidate <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">form-horizontal</span><span style="color: #800000;">"</span>><span style="color: #000000;"> | |
| {</span>% csrf_token %<span style="color: #000000;">} | |
| </span><div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">form-group</span><span style="color: #800000;">"</span>> | |
| <label <span style="color: #0000ff;">for</span>=<span style="color: #800000;">"</span><span style="color: #800000;">{{ form_obj.username.id_for_label }}</span><span style="color: #800000;">"</span> | |
| <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">col-md-2 control-label</span><span style="color: #800000;">"</span>>{{ form_obj.username.label }}</label> | |
| <div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">col-md-10</span><span style="color: #800000;">"</span>><span style="color: #000000;"> | |
| {{ form_obj.username }} | |
| </span><span <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">help-block</span><span style="color: #800000;">"</span>>{{ form_obj.username.errors.0 }}</span> | |
| </div> | |
| </div> | |
| <div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">form-group</span><span style="color: #800000;">"</span>> | |
| <label <span style="color: #0000ff;">for</span>=<span style="color: #800000;">"</span><span style="color: #800000;">{{ form_obj.pwd.id_for_label }}</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">col-md-2 control-label</span><span style="color: #800000;">"</span>>{{ form_obj.pwd.label }}</label> | |
| <div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">col-md-10</span><span style="color: #800000;">"</span>><span style="color: #000000;"> | |
| {{ form_obj.pwd }} | |
| </span><span <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">help-block</span><span style="color: #800000;">"</span>>{{ form_obj.pwd.errors.0 }}</span> | |
| </div> | |
| </div> | |
| <div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">form-group</span><span style="color: #800000;">"</span>> | |
| <label <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">col-md-2 control-label</span><span style="color: #800000;">"</span>>{{ form_obj.gender.label }}</label> | |
| <div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">col-md-10</span><span style="color: #800000;">"</span>> | |
| <div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">radio</span><span style="color: #800000;">"</span>><span style="color: #000000;"> | |
| {</span>% <span style="color: #0000ff;">for</span> radio <span style="color: #0000ff;">in</span> form_obj.gender %<span style="color: #000000;">} | |
| </span><label <span style="color: #0000ff;">for</span>=<span style="color: #800000;">"</span><span style="color: #800000;">{{ radio.id_for_label }}</span><span style="color: #800000;">"</span>><span style="color: #000000;"> | |
| {{ radio.tag }}{{ radio.choice_label }} | |
| </span></label><span style="color: #000000;"> | |
| {</span>% endfor %<span style="color: #000000;">} | |
| </span></div> | |
| </div> | |
| </div> | |
| <div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">form-group</span><span style="color: #800000;">"</span>> | |
| <div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">col-md-offset-2 col-md-10</span><span style="color: #800000;">"</span>> | |
| <button type=<span style="color: #800000;">"</span><span style="color: #800000;">submit</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">btn btn-default</span><span style="color: #800000;">"</span>>注册</button> | |
| </div> | |
| </div> | |
| </form> | |
| </div> | |
| </div> | |
| <script src=<span style="color: #800000;">"</span><span style="color: #800000;">/static/jquery-3.2.1.min.js</span><span style="color: #800000;">"</span>></script> | |
| <script src=<span style="color: #800000;">"</span><span style="color: #800000;">/static/bootstrap/js/bootstrap.min.js</span><span style="color: #800000;">"</span>></script> | |
| </body> | |
| </html></pre> | |
| </div> | |
| <span class="likecs_code_collapse">Django form应用Bootstrap样式简单示例</span></div> | |
| <h3>批量添加样式</h3> | |
| <p>可通过重写form类的init方法来实现。</p> | |
| <div class="likecs_code" onclick="likecs_code_show('c649c7f6-257f-4d08-94e0-7e8187f297cd')"><img /> | |
| <div > | |
| <pre><span style="color: #0000ff;">class</span><span style="color: #000000;"> LoginForm(forms.Form): | |
| username </span>=<span style="color: #000000;"> forms.CharField( | |
| min_length</span>=8<span style="color: #000000;">, | |
| label</span>=<span style="color: #800000;">"</span><span style="color: #800000;">用户名</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| initial</span>=<span style="color: #800000;">"</span><span style="color: #800000;">张三</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| error_messages</span>=<span style="color: #000000;">{ | |
| </span><span style="color: #800000;">"</span><span style="color: #800000;">required</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">不能为空</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| </span><span style="color: #800000;">"</span><span style="color: #800000;">invalid</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">格式错误</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| </span><span style="color: #800000;">"</span><span style="color: #800000;">min_length</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">用户名最短8位</span><span style="color: #800000;">"</span><span style="color: #000000;"> | |
| } | |
| ... | |
| </span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__init__</span>(self, *args, **<span style="color: #000000;">kwargs): | |
| super(LoginForm, self).</span><span style="color: #800080;">__init__</span>(*args, **<span style="color: #000000;">kwargs) | |
| </span><span style="color: #0000ff;">for</span> field <span style="color: #0000ff;">in</span><span style="color: #000000;"> iter(self.fields): | |
| self.fields[field].widget.attrs.update({ | |
| </span><span style="color: #800000;">'</span><span style="color: #800000;">class</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">form-control</span><span style="color: #800000;">'</span><span style="color: #000000;"> | |
| })</span></pre> | |
| </div> | |
| <span class="likecs_code_collapse">批量添加样式</span></div> | |
| <h1>ModelForm</h1> | |
| <p>通常在Django项目中,我们编写的大部分都是与Django 的模型紧密映射的表单。 举个例子,你也许会有个Book 模型,并且你还想创建一个form表单用来添加和编辑书籍信息到这个模型中。 在这种情况下,在form表单中定义字段将是冗余的,因为我们已经在模型中定义了那些字段。</p> | |
| <p>基于这个原因,Django 提供一个辅助类来让我们可以从Django 的模型创建Form,这就是ModelForm。</p> | |
| <h2>modelForm定义</h2> | |
| <p>form与model的终极结合。</p> | |
| <div class="likecs_code"> | |
| <pre><span style="color: #0000ff;">class</span><span style="color: #000000;"> BookForm(forms.ModelForm): | |
| </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> Meta: | |
| model </span>=<span style="color: #000000;"> models.Book | |
| fields </span>= <span style="color: #800000;">"</span><span style="color: #800000;">__all__</span><span style="color: #800000;">"</span><span style="color: #000000;"> | |
| labels </span>=<span style="color: #000000;"> { | |
| </span><span style="color: #800000;">"</span><span style="color: #800000;">title</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">书名</span><span style="color: #800000;">"</span><span style="color: #000000;">, | |
| </span><span style="color: #800000;">"</span><span style="color: #800000;">price</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">价格</span><span style="color: #800000;">"</span><span style="color: #000000;"> | |
| } | |
| widgets </span>=<span style="color: #000000;"> { | |
| </span><span style="color: #800000;">"</span><span style="color: #800000;">password</span><span style="color: #800000;">"</span>: forms.widgets.PasswordInput(attrs={<span style="color: #800000;">"</span><span style="color: #800000;">class</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">c1</span><span style="color: #800000;">"</span><span style="color: #000000;">}), | |
| }</span></pre> | |
| </div> | |
| <h3>class Meta下常用参数:</h3> | |
| <div class="likecs_code"> | |
| <pre>model =<span style="color: #000000;"> models.Book # 对应的Model中的类 | |
| fields </span>= <span style="color: #800000;">"</span><span style="color: #800000;">__all__</span><span style="color: #800000;">"</span><span style="color: #000000;"> # 字段,如果是__all__,就是表示列出所有的字段 | |
| exclude </span>=<span style="color: #000000;"> None # 排除的字段 | |
| labels </span>=<span style="color: #000000;"> None # 提示信息 | |
| help_texts </span>=<span style="color: #000000;"> None # 帮助提示信息 | |
| widgets </span>=<span style="color: #000000;"> None # 自定义插件 | |
| error_messages </span>= None # 自定义错误信息</pre> | |
| </div> | |
| <h3>ModelForm的验证</h3> | |
| <p>与普通的Form表单验证类型类似,ModelForm表单的验证在调用is_valid() 或访问errors 属性时隐式调用。</p> | |
| <p>我们可以像使用Form类一样自定义局部钩子方法和全局钩子方法来实现自定义的校验规则。</p> | |
| <p>如果我们不重写具体字段并设置validators属性的化,ModelForm是按照模型中字段的validators来校验的。</p> | |
| <h3>save()方法</h3> | |
| <p>每个ModelForm还具有一个save()方法。 这个方法根据表单绑定的数据创建并保存数据库对象。 ModelForm的子类可以接受现有的模型实例作为关键字参数instance;如果提供此功能,则save()将更新该实例。 如果没有提供,save() 将创建模型的一个新实例:</p> | |
| <div class="likecs_code"> | |
| <pre>>>> <span style="color: #0000ff;">from</span> myapp.models <span style="color: #0000ff;">import</span><span style="color: #000000;"> Book | |
| </span>>>> <span style="color: #0000ff;">from</span> myapp.forms <span style="color: #0000ff;">import</span><span style="color: #000000;"> BookForm | |
| </span><span style="color: #008000;">#</span><span style="color: #008000;"> 根据POST数据创建一个新的form对象</span> | |
| >>> form_obj =<span style="color: #000000;"> BookForm(request.POST) | |
| </span><span style="color: #008000;">#</span><span style="color: #008000;"> 创建书籍对象</span> | |
| >>> new_ book =<span style="color: #000000;"> form_obj.save() | |
| </span><span style="color: #008000;">#</span><span style="color: #008000;"> 基于一个书籍对象创建form对象</span> | |
| >>> edit_obj = Book.objects.get(id=1<span style="color: #000000;">) | |
| </span><span style="color: #008000;">#</span><span style="color: #008000;"> 使用POST提交的数据更新书籍对象</span> | |
| >>> form_obj = BookForm(request.POST, instance=<span style="color: #000000;">edit_obj) | |
| </span>>>> form_obj.save()</pre> | |
| </div> | |
| <p> </p></div><div ></div> | |
| <div class="clear"></div> | |
| <div > | |
| <div ></div> | |
| <div ></div> | |
| <div > | |
| </div> | |
| <div class="clear"></div> | |
| <div ></div> | |
| </div> | |
| </div> | |
| <div class = "postDesc">posted @ <span ></div> | |
| </div> | |
| <script type="text/javascript">var allowComments=false,cb_blogId=260599,cb_entryId=8747872,cb_blogApp=currentBlogApp,cb_blogUserGuid='ae376d01-5dac-e511-9fc1-ac853d9f53cc',cb_entryCreatedDate='2018/4/8 22:13:00';loadViewCount(cb_entryId);var cb_postType=1;</script> | |
| </div><!--end: topics 文章、评论容器--> | |
| </div><a name="!comments"></a><div ></script> | |
| <div id='comment_form' class='commentform'> | |
| <a name='commentform'></a> | |
| <div id='divCommentShow'></div> | |
| <div id='comment_nav'><span id='span_refresh_tips'></span><a href='javascript:void(0);' onclick='return RefreshCommentList();' id='lnk_RefreshComments' runat='server' clientidmode='Static'>刷新评论</a><a href='#' onclick='return RefreshPage();'>刷新页面</a><a href='#top'>返回顶部</a></div> | |
| <div id='comment_form_container'></div> | |
| <div class='ad_text_commentbox' id='ad_text_under_commentbox'></div> | |
| <div id='ad_t2'></div> | |
| <div id='opt_under_post'></div> | |
| <div id='likecs_c1' class='c_ad_block'></div> | |
| <div id='under_post_news'></div> | |
| <script async='async' src='https://www.googletagservices.com/tag/js/gpt.js'></script> | |
| <script> | |
| var googletag = googletag || {}; | |
| googletag.cmd = googletag.cmd || []; | |
| </script> | |
| <script> | |
| googletag.cmd.push(function() { | |
| googletag.defineSlot('/1090369/C2', [468, 60], 'div-gpt-ad-1539008685004-0').addService(googletag.pubads()); | |
| googletag.pubads().enableSingleRequest(); | |
| googletag.enableServices(); | |
| }); | |
| </script> | |
| <div id='likecs_c2' class='c_ad_block'> | |
| <div id='div-gpt-ad-1539008685004-0' style='height:60px; width:468px;'> | |
| <script> | |
| if (new Date() >= new Date(2018, 9, 13)) { | |
| googletag.cmd.push(function() { googletag.display('div-gpt-ad-1539008685004-0'); }); | |
| } | |
| </script> | |
| </div> | |
| </div> | |
| <div id='under_post_kb'></div> | |
| <div id='HistoryToday' class='c_ad_block'></div> | |
| <script type='text/javascript'> | |
| fixPostBody(); | |
| setTimeout(function () { incrementViewCount(cb_entryId); }, 50); | |
| deliverAdT2(); | |
| deliverAdC1(); | |
| deliverAdC2(); | |
| loadNewsAndKb(); | |
| loadBlogSignature(); | |
| LoadPostInfoBlock(cb_blogId, cb_entryId, cb_blogApp, cb_blogUserGuid); | |
| GetPrevNextPost(cb_entryId, cb_blogId, cb_entryCreatedDate, cb_postType); | |
| loadOptUnderPost(); | |
| GetHistoryToday(cb_blogId, cb_blogApp, cb_entryCreatedDate); | |
| </script> | |
| </div> | |
| </div><!--end: forFlow --> | |
| </div><!--end: mainContent 主体内容容器--> | |
| <div > | |
| <div > | |
| <!--done--> | |
| <div class="newsItem"> | |
| <h3 class="catListTitle">公告</h3> | |
| <div ></script> | |
| </div> | |
| <div ></script> | |
| <div > | |
| <div ></script> | |
| </div> | |
| </div><!--end: sideBarMain --> | |
| </div><!--end: sideBar 侧边栏容器 --> | |
| <div class="clear"></div> | |
| </div><!--end: main --> | |
| <div class="clear"></div> | |
| <div > | |
| <!--done--> | |
| Copyright ©2018 Q1mi | |
| </div><!--end: footer --> | |
| </div><!--end: home 自定义的最大容器 --> | |
| <!--PageEndHtml Block Begin--> | |
| <script src="https://files.cnblogs.com/files/miangao/bootstrap.min.js"></script> | |
| <!--PageEndHtml Block End--> | |
| </body> | |
| </html> | |
相关文章: