一,创建一个表单
创建一个Form表单有两种方式:
第一种方式是继承于forms.Form,的一个子类,通过在form中选择你需要的类型来规定表单之
中字段的类型
class LoginForm(forms.Form): username = forms.CharField(max_length=15, min_length=5, #onblur = "Check(this)", error_messages={ 'required': u'不能为空', 'min_length':u'最少为5个字符', 'max_length':u'最多为20个字符', }, widget=forms.TextInput(attrs={'class':"form-control", 'placeholder':u'5-20个字符', 'onblur' : "Check(this)", })) password = forms.CharField(widget=forms.PasswordInput, max_length=20, min_length=6, error_messages={ 'required': u'不能为空', 'min_length':u'最少为6个字符', 'max_length':u'最多为20个字符', })
其中 django 内置了很多的字段,让开发者可以直接使用,并且内置了这些字段的检验使站点中的表单数据检测变得方便,也提供了一些可选择的检验规则如required=False等,具体的可以去Django 官网查询API。
第二种 是直接利用数据库中以有的表来生成表单项, 这对于一个管理系统类型的网站 比较有用,因为如果一个站点有大量的实体数据需要让用户输入,那么就不必重新花费时间来定义表单,只需要直接的和 model 进行关联就可以了如:
from web_models import models class LoginForm(forms.ModelForm): class Meta: model = models.AdminInfo#直接通过数据的表生成表单。直接关联到了数据库的列名 fields = ('username', 'password')#只从AdminInfo表中拿这两个字段,用来生成表单 #通过widgets这个参数,手动的设定字段以何种input类型显示 widgets = { 'username': forms.TextInput(attrs={'class': "form-control", 'placeholder': "用户名"}), 'password': forms.PasswordInput(attrs={'class': "form-control",'placeholder': "密码"}), }
class Meta: model = models.AdminInfo exclude = ('user_info',)#exclude 属性用来固定哪些字段不想生成到表单中
fields和exclude 两个字段用一个就行
二、使用表单
在视图中使用
在视图中使用一个表单的两种功能,一是创建一个表单让用户来填写信息;另一个是处理表单中的数据。
创建一个表单就是直接实例化一个表单对象:
formx = LoginForm()
form = ContactForm(),里面有几个比较重要的参数:auto_id=False这个参数 主要是表示 是否在表单中生成 id ,因为有的时候你不想让你每个表单的字段都对应一个id, 如果生成 默认id是 id_form字段名字.
设置默认值
可以在创建 表单对象时传入如下参数initial={}
这是一个字典参数,对应每个字段的默认值, 可以在定义表的时候在没定义一个时段 中添加 initial='http://' 来设定默认值
更新数据
你可能需要 用一个 model实例来初始化他,这样就可以达到表单更新数据
f = ArticleForm(instance=a) 其中 a 是article 的一个model实例。
提取数据
在 处理 post 请求时候, 通过 f = ArticleForm(request.POST)来获取一个填有用户数据的form
在调用了 is_valid 方法以后 就可以通过 f.cleaned_data ,返回一个 装有数据的字典
三、关于django form表单的其他说明
1)form类的运行顺序是init,clean,validte,save
其中clean和validate会在form.is_valid()方法中被先后调用。
下面为在views中处理表单
def login(request): error = '' login_form = LoginForm(request.POST) if request.method == 'POST': check = request.POST.get('checkcode',None) if check != request.session['CheckCode'].lower(): error = '验证码错误.' else: if not login_form.is_valid():# 数据验证 error = '用户名或密码格式错误.' else: data = login_form.clean()#放到login_from对象的字典里,数据的获取 result = account_manager.check_valid(**data) if result.status: ret = {'id': result.data.user_info.id, 'name': result.data.user_info.name} request.session['auth_user'] = json.dumps(ret) target = request.GET.get('back', '/home/index/') return redirect(target) else: error = '用户名或密码错误.' return render_to_response('account/login.html', {'model': login_form,'error': error})
2)clean方法返回值
如果字段定义charfield,那么clean方法返回的cleaned_data中对应的字段值就是字符型,
定义为ModelMultipleChoiceField,则cleaned_data中字段值是个model实例list。
3)上面案例中的应用
ModelForm的Meta类中定义的fields:默认的Field是Model中定义的Field,如需更改,可在Form类内以同名字段覆盖,如上图第二段代码中;
不管字段在form中怎么自定义,cleaned_data中对应的值都必须按照model中定义的字段类型取值。
四、前台login.html代码,只有HTML部分。作为一个参考,样式没有附带
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.min.css"/> <link rel="stylesheet" href="/static/plugins/font-awesome/css/font-awesome.min.css"/> <link rel="stylesheet" href="/static/css/commons.css"/> <link rel="stylesheet" href="/static/css/account.css"/> </head> <body> <div class="login-container"> <div class="account-body clearfix"> <div class="logo left"> <img style='height:100%;width: 100%;' src="/static/images/login.png" /> </div> <div class="form left"> <div style="margin: 10px 60px 0 60px;"> <form id="Form" method="POST"> {% if error %} <div class="alert alert-danger" role="alert"> <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> <span class="sr-only">Error:</span> {{ error }} </div> {% else %} <div style="height: 30px;"> </div> {% endif %} <div class="input-group"> <span class="input-group-addon"><i class="fa fa-user"></i></span> {{ model.username }} </div> <div class="input-group"> <span class="input-group-addon"><i class="fa fa-lock"></i></span> {{ model.password }} </div> <div class="input-group"> <span class="input-group-addon"><i class="fa fa-pencil-square-o"></i></span> <input type="text" name="checkcode" class="form-control check-code" placeholder="验证码"> <img onclick='ChangeCode();' id='imgCode' src="/account/checkcode/"> </div> <div class="input-group"> <span class="check"><input type="checkbox" ></span> <span>自动登录</span> <span style="margin-left: 50px"><a href="#">忘记密码</a></span> </div> <div class="input-group"> <input type="submit" class="btn btn-primary" value="登 陆" /> <input type="reset" class="btn btn-primary" value="重 置" /> </div> </form> </div> </div> </div> </div> <script src='/static/js/jquery-1.8.2.min.js'></script> <script src='/static/js/valid.js'></script> <script type="text/javascript"> $(function(){ $.login('#Form',''); }) function ChangeCode() { var code = document.getElementById('imgCode'); code.src += '?'; } function(form,summaryStatusId){ $(form).find(':submit').click(function(){ var flag = true; $(form).find(':text,:password').each(function(){ var name = $(this).attr('name'); var label = $(this).attr('placeholder'); var val = $(this).val(); var $parent = $(this).parent(); if(!val || val.trim() == ''){ flag = false; ErrorMessage($parent,label+'不能为空.'); return false; } EmptyError($parent); }); return flag; }); } </script> </body> </html>
ps:本文为一个django 使用forms 登入的前台案例,还未完善
ps:上面所用代码 大多来自 django book 和 django官网API ,更多的问题请留言