最近在学习Django的过程中,发现Django里面对表单的支持非常棒,简化了很多操作,例如可以很方便的生成Html表单,对表单进行验证以及最终的数据存储等等,简单的一个实例如下:
class AccountForm(forms.ModelForm): nick_name = forms.CharField(label=u'用户昵称', \ help_text="请输入用户昵称") email = forms.EmailField(label=u'电子邮件', \ help_text=u'请输入常用邮箱') password = forms.CharField(label=u'密码', \ help_text=u'请输入密码', \ widget=forms.PasswordInput()) re_password = forms.CharField(label=u'确认密码', \ help_text=u'请再次确认密码', \ widget=forms.PasswordInput()) def clean_re_password(self): password = self.cleaned_data.get("password") re_password = self.cleaned_data.get("re_password") if password and re_password and password != re_password: raise forms.ValidationError((u'密码输入不一致')) if len(password) < 6: raise forms.ValidationError((u'密码至少6位')) return re_password class Meta: model = Account fields = ('nick_name', 'email', 'password')
在模板中只需要简单的添加
<div class="weui_cells_form"> <form id="user_form" method="post" action="url_to_submit_form" <!-- csrf_token fields is necessary for securty --> {% csrf_token %} {{account_form}} <input type="submit" name="submit" value="注册" /> </form> </div>
这样就完成了简单的表单设计。
Django的这种方法确实很简单,但是Django固有的表单样式比较单一,虽然可以通过widget属性添加css样式,但是明显DIY程度不够高,本着前后端分离的原则,需要将表单的样式彻底分离出来,做到完全定制。
具体的表单自定义方式实际在Django的官方文档里面也有提及
Useful attributes on {{ field }} include: {{ field.label }} The label of the field, e.g. Email address. {{ field.label_tag }} The field’s label wrapped in the appropriate HTML <label> tag. This includes the form’s label_suffix. For example, the default label_suffix is a colon: <label for="id_email">Email address:</label> {{ field.id_for_label }} The ID that will be used for this field (id_email in the example above). If you are constructing the label manually, you may want to use this in lieu of label_tag. It’s also useful, for example, if you have some inline JavaScript and want to avoid hardcoding the field’s ID. {{ field.value }} The value of the field. e.g [email protected] {{ field.html_name }} The name of the field that will be used in the input element’s name field. This takes the form prefix into account, if it has been set. {{ field.help_text }} Any help text that has been associated with the field. {{ field.errors }} Outputs a <ul class="errorlist"> containing any validation errors corresponding to this field. You can customize the presentation of the errors with a {% for error in field.errors %} loop. In this case, each object in the loop is a simple string containing the error message. {{ field.is_hidden }}
通过这种方式,就可以实现对Form的完全定制,比如采用微信的样式:
<div class="weui_cells weui_cells_form"> {% for item in login_form %} <div class="weui_cell"> <div class="weui_cell_hd"> <label class="weui_label">{{item.label}}</label> </div> <div class="weui_cell_bd weui_cell_primary"> <input class="weui_input" placeholder="{{item.help_text}}" id="{{item.id_for_label}}" name="{{item.html_name}}" type="{{item.field.widget.input_type}}" /> </div> {% for error in item.errors %} <p>{{error}}</p> {% endfor%} </div> </div>
在上面的”item.field.widget.input_type”这个域在文档中也并未提及,但是这个域又相当重要,因为像输入密码日期之类的类型都是靠这个域来定义的,最后这个域是通过读Django的源代码得到的,也算是一种获得Doc的途径吧。
原创文章,作者:Y4er,未经授权禁止转载!如若转载,请联系作者:Y4er