Django Form表单
来源:互联网 发布:网络包工头在哪找活 编辑:程序博客网 时间:2024/06/05 06:09
Django Form表单的好处
- 对用户提交的数据验证
- 自动生成错误信息
- 打包用户提交的正确信息
- 能够在input框里保留上次输入的错误信息
- 定制页面的html标签
构建一个Form表单
创建form类
from django.forms import Form,fields,widgetsfrom django.core.validators import RegexValidatorfrom django.core.exceptions import ValidationErrorfrom blog import modelsclass RegisterForm(Form): email = fields.CharField( required=True, error_messages={"required":"邮箱不能为空"}, widget=widgets.EmailInput(attrs={"placeholder":"需要通过邮箱激活账户","class":"form-control",}), validators=[RegexValidator("[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?","请输入正确的邮箱格式")] ) telephone = fields.CharField( required=True, error_messages={"required": "手机号不能为空"}, widget=widgets.EmailInput(attrs={"placeholder": "需要通过手机号激活账户", "class": "form-control"}), validators=[RegexValidator( "^1(3|4|5|7|8)\d{9}$","手机号码有误")] ) username = fields.CharField( required=True, min_length=4, error_messages={ "required":"用户名不能为空", "min_length":"用户名不能少于4个字符", }, widget=widgets.TextInput(attrs={"placeholder":"登录用户名,不少于4个字符","class":"form-control"}) ) nick_name = fields.CharField( required=True, min_length=2, error_messages={ "required": "昵称不能为空", "min_length": "昵称不能少于2个字符", }, widget=widgets.TextInput(attrs={"placeholder": "昵称,不少于2个字符", "class": "form-control"}) ) password = fields.CharField( required=True, min_length=8, error_messages={ "required": "密码不能为空", "min_length": "密码不能少于8个字符", }, widget=widgets.PasswordInput(attrs={"placeholder": "至少8位,且必须包含字母,数字,特殊字符", "class": "form-control"}), validators=[RegexValidator("^(?![a-zA-Z0-9]+$)(?![^a-zA-Z/D]+$)(?![^0-9/D]+$).{10,20}$","密码必须包含字母,数字,特殊符号")] ) repeat_password = fields.CharField( required=True, error_messages={ "required": "密码不能为空", }, widget=widgets.PasswordInput( attrs={"placeholder": "请再次输入密码", "class": "form-control"}), ) def clean_username(self):#局部钩子 username = models.UserInfo.objects.filter(username=self.cleaned_data.get("username")) if not username: return self.cleaned_data.get("username") else: raise ValidationError("用户名已存在") def clean_email(self):#局部钩子 email = models.UserInfo.objects.filter(email = self.cleaned_data.get("email")) if not email: return self.cleaned_data.get("email") else: raise ValidationError("邮箱已注册") def clean(self):#全局钩子 password = self.cleaned_data.get("password") repeat_password = self.cleaned_data.get("repeat_password") if password == repeat_password: return self.cleaned_data else: raise ValidationError("两次输入的密码不一致")
视图
def register(request): if request.method == "GET": form = RegisterForm() return render(request, 'register.html', {"form": form}) elif request.is_ajax(): form = RegisterForm(request.POST) registerResponse = {"user": None, "error_list": None} # print(type(form)) if form.is_valid(): email = form.cleaned_data.get("email") telephone = form.cleaned_data.get("telephone") username = form.cleaned_data.get("username") nick_name = form.cleaned_data.get("nick_name") password = form.cleaned_data.get("password") avatar_img = request.FILES.get("avatar_img") models.UserInfo.objects.create_user(email=email, telephone=telephone, username=username, nick_name=nick_name, password=password, avatar=avatar_img) registerResponse["user"] =form.cleaned_data.get("username") print(registerResponse["user"]) else: registerResponse["error_list"] = form.errors return HttpResponse(json.dumps(registerResponse))
模板
<!DOCTYPE html> //实现一个简单的注册功能,结合form,ajax<html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/sweet/sweetalert2.min.css"> <link rel="stylesheet" href="/static/css/register.css"> <script src="/static/js/jquery-3.2.1.min.js"></script> <script src="/static/js/bootstrap.min.js"></script> <script src="/static/js/jquery.cookie.js"></script> <script src="/static/sweet/sweetalert2.min.js"></script> <style type="text/css"> .my-navbar a { background: transparent !important; color: #fff !important } .my-navbar a:hover { color: #45bcf9 !important; background: transparent; outline: 0 } #input{ color: red; } .avatar{ position: relative; width: 60px; height: 60px; } #avatar_file,#avatar_img{ position:absolute; top:0; left: 20px; width: 60px; height: 60px; } #avatar_file{ opacity: 0; } </style></head><body style="background-color: #f8f8f8"><nav class="navbar navbar-inverse navbar-fixed-top my-navbar"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#" style="font-size: 30px">博 客 苑</a> </div> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav navbar-right"> <li><a href=""><span class="glyphicon glyphicon-home " style="font-size: 15px"></span> 首 页</a> </li> <li><a href="/sign_in/"><span class="glyphicon glyphicon-user" style="font-size: 15px"></span> 登 录</a> </li> <li><a href="/register/"><span class="glyphicon glyphicon-user" style="font-size: 15px"><span class=" glyphico glyphicon-plus-sign" style="font-size: 2px;"></span></span> 注 册</a> </li> </ul> </div> </div></nav><div class="container" style="margin-top: 100px"> <div class="row col-md-11 "> <div class="col-md-offset-1"> <h3>注册新用户</h3> <hr> </div> <div class="col-md-7"> <form class="form-horizontal" id="s1" method="post" novalidate> {% csrf_token %} <div class="form-group"> <label for="inputEmail" class="col-sm-3 control-label col-md-offset-1">邮 箱:</label> <div class="col-md-8"> {{ form.email }}//form表单自动生成input框 </div> </div> <div class="form-group"> <label for="inputPhone" class="col-sm-3 control-label col-md-offset-1">手机号码:</label> <div class="col-md-8"> {{ form.telephone }} </div> </div> <div class="form-group"> <label for="inputUser" class="col-sm-3 control-label col-md-offset-1">用户名称:</label> <div class="col-md-8"> {{ form.username }} </div> </div> <div class="form-group"> <label for="inputNickname" class="col-sm-3 control-label col-md-offset-1">昵 称:</label> <div class="col-md-8"> {{ form.nick_name }} </div> </div> <div class="form-group"> <label for="inputPassword" class="col-sm-3 control-label col-md-offset-1">密 码:</label> <div class="col-md-8"> {{ form.password }} </div> </div> <div class="form-group"> <label for="inputRepeatPassword" class="col-sm-3 control-label col-md-offset-1">确认密码:</label> <div class="col-md-8"> {{ form.repeat_password }} </div> </div> <div class="form-group"> <label for="inputRepeatPassword" class="col-sm-3 control-label col-md-offset-1">头像:</label> <div class="col-md-8 avatar"> <a href=""><img src="/static/img/default.png" alt="" id="avatar_img"></a> <input type="file" class="form-control" id="avatar_file"> </div> </div> <div class="form-group"> <div class="col-md-2" style="margin-left:330px"> <input type="button" value="注 册" class="form-control btn-primary" id="register"> </div> </div> <div style="margin-left:230px"> <span>点击"注册"按钮,表示您已同意和遵守<a href="">用户协议</a></span> </div> </form> </div> <div class="col-sm-1"> <table style="height:280px;border-color:#cccccc;border-left-style:solid;border-width:1px"> <tr> <td valign="top"></td> </tr> </table> </div> <div class="col-md-4"> <img src="/static/img/registersideimg.png" alt="" style="width: 300px;height: 280px;border-radius: 8px"> </div> </div></div><script> //头像预览$("#avatar_file").change(function () { //this.files var ele_file = $(this)[0].files[0];//获取当前文件 var read = new FileReader();//实例化read对象 read.readAsDataURL (ele_file);//获取当前文件的url read.onload = function () { $("#avatar_img").attr("src",this.result);//this.result 就是read.readAsDataURL获取到的url路径 }});//注册校验$("#register").on("click",function () { var formData = new FormData();//实例化formData对象 formData.append("email",$("#id_email").val());//获取email值 formData.append("telephone",$("#id_telephone").val());//获取telephone值 formData.append("username",$("#id_username").val());//获取username值 formData.append("nick_name",$("#id_nick_name").val());//获取nick_name值 formData.append("password",$("#id_password").val());//获取password值 formData.append("repeat_password",$("#id_repeat_password").val());//获取repeat_password值 formData.append("avatar_img",$("#avatar_file")[0].files[0]);//获取文件二进制 $(".pull-right").html(""); $(".pull-right").parent().removeClass("has-error"); $.ajax({ url:"/register/", type:"POST", data:formData, headers: {"X-CSRFToken": $.cookie('csrftoken')}, contentType:false,//必须加的字段,不加的话二进制文件传不过去 processData:false, success:function (data) { var dat = JSON.parse(data); console.log(dat); if (dat.user){ location.href = "/sign_in/" } else{ //jquery循环取出error_list里面的键值对 $.each(dat.error_list,function (i,j) { console.log(i,j); $span = $("<span>");//造span标签 $span.addClass("pull-right").css("color","red");//让span标签显示在右边 $span.html(j[0]);//给span赋值 $("#id_"+i) .after($span).parent().addClass("has-error"); if (i == "__all__"){ $("input[name=repeat_password]").after($span); } }) } } })})</script></body></html>
form补充
1 django内置字段
Field required=True, 是否允许为空 widget=None, HTML插件 label=None, 用于生成Label标签或显示内容 initial=None, 初始值 help_text='', 帮助信息(在标签旁边显示) error_messages=None, 错误信息 {'required': '不能为空', 'invalid': '格式错误'} show_hidden_initial=False, 是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直) validators=[], 自定义验证规则 localize=False, 是否支持本地化 disabled=False, 是否可以编辑 label_suffix=None Label内容后缀CharField(Field) max_length=None, 最大长度 min_length=None, 最小长度 strip=True 是否移除用户输入空白IntegerField(Field) max_value=None, 最大值 min_value=None, 最小值FloatField(IntegerField) ...DecimalField(IntegerField) max_value=None, 最大值 min_value=None, 最小值 max_digits=None, 总长度 decimal_places=None, 小数位长度BaseTemporalField(Field) input_formats=None 时间格式化 DateField(BaseTemporalField) 格式:2015-09-01TimeField(BaseTemporalField) 格式:11:12DateTimeField(BaseTemporalField)格式:2015-09-01 11:12DurationField(Field) 时间间隔:%d %H:%M:%S.%f ...RegexField(CharField) regex, 自定制正则表达式 max_length=None, 最大长度 min_length=None, 最小长度 error_message=None, 忽略,错误信息使用 error_messages={'invalid': '...'}EmailField(CharField) ...FileField(Field) allow_empty_file=False 是否允许空文件ImageField(FileField) ... 注:需要PIL模块,pip3 install Pillow 以上两个字典使用时,需要注意两点: - form表单中 enctype="multipart/form-data" - view函数中 obj = MyForm(request.POST, request.FILES)URLField(Field) ...BooleanField(Field) ...NullBooleanField(BooleanField) ...ChoiceField(Field) ... choices=(), 选项,如:choices = ((0,'上海'),(1,'北京'),) required=True, 是否必填 widget=None, 插件,默认select插件 label=None, Label内容 initial=None, 初始值 help_text='', 帮助提示ModelChoiceField(ChoiceField) ... django.forms.models.ModelChoiceField queryset, # 查询数据库中的数据 empty_label="---------", # 默认空显示内容 to_field_name=None, # HTML中value的值对应的字段 limit_choices_to=None # ModelForm中对queryset二次筛选ModelMultipleChoiceField(ModelChoiceField) ... django.forms.models.ModelMultipleChoiceFieldTypedChoiceField(ChoiceField) coerce = lambda val: val 对选中的值进行一次转换 empty_value= '' 空值的默认值MultipleChoiceField(ChoiceField) ...TypedMultipleChoiceField(MultipleChoiceField) coerce = lambda val: val 对选中的每一个值进行一次转换 empty_value= '' 空值的默认值ComboField(Field) fields=() 使用多个验证,如下:即验证最大长度20,又验证邮箱格式 fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),])MultiValueField(Field) PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用SplitDateTimeField(MultiValueField) input_date_formats=None, 格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y'] input_time_formats=None 格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M']FilePathField(ChoiceField) 文件选项,目录下文件显示在页面中 path, 文件夹路径 match=None, 正则匹配 recursive=False, 递归下面的文件夹 allow_files=True, 允许文件 allow_folders=False, 允许文件夹 required=True, widget=None, label=None, initial=None, help_text=''GenericIPAddressField protocol='both', both,ipv4,ipv6支持的IP格式 unpack_ipv4=False 解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用SlugField(CharField) 数字,字母,下划线,减号(连字符) ...UUIDField(CharField) uuid类型 ...
2 django 内置插件
TextInput(Input)NumberInput(TextInput)EmailInput(TextInput)URLInput(TextInput)PasswordInput(TextInput)HiddenInput(TextInput)Textarea(Widget)DateInput(DateTimeBaseInput)DateTimeInput(DateTimeBaseInput)TimeInput(DateTimeBaseInput)CheckboxInputSelectNullBooleanSelectSelectMultipleRadioSelectCheckboxSelectMultipleFileInputClearableFileInputMultipleHiddenInputSplitDateTimeWidgetSplitHiddenDateTimeWidgetSelectDateWidget
3 表单渲染
对于<label>/<input> 对,还有几个输出选项:{{ form.as_table }} 以表格的形式将它们渲染在<tr> 标签中{{ form.as_p }} 将它们渲染在<p> 标签中{{ form.as_ul }} 将它们渲染在<li> 标签中可以用这种方式生成,但推荐使用,不灵活,不易控
阅读全文
0 0
- Django Form表单
- Django form表单使用
- Django Form表单
- Django中的Form表单
- Django表单form
- Django的form表单
- Django Form表单
- 千与千寻django(七)---表单(form)
- Django中 form表单的使用
- Django中 form表单的使用
- django学习08---Form表单提交
- Form表单(Django系列5)
- Django中 form表单的使用
- Django中 form表单的使用
- 【django】表单 Form类1(django.forms)
- Django(七)----Django的用户认证,form表单
- [Django与表单]写一个简单的Django form表单处理
- 【django】表单Form类2-自定义校验规则
- 第一个java程序的编译和运行(linux下安装JDK)------一次编译,到处运行
- 3、 find_element
- 参考文献格式国家标准(GB-T 7714-2005)
- Hibernate映射关联(2)
- FFMPEG filter使用实例(实现视频缩放,裁剪,水印等)
- Django Form表单
- 171115 杂项-可见字符组成的Shellcode
- 类的加载过程
- D. Ralph And His Tour in Binary Country
- 类加载机制
- 3分钟教你成为JVM的尖子生
- Java性能权威指南.pdf 免费下载
- Redis实战.pdf 免费下载
- 【数据结构】循环队列的顺序实现