9.24 Django Form组件
2018-9-23 20:10:04
这两天优化了自己图书管理系统
github 连接:https://github.com/TrueNewBee/pythonDemo
顺便整理了博客,写了好多总结,都发表自己博客文章了
放上连接 https://www.cnblogs.com/zhen1996/category/1306698.html
明天再看 day73视频
form 参考连接:http://www.cnblogs.com/liwenzhou/p/8747872.html
2018-9-24 14:28:04
2018-9-24 19:42:38
昨天成功爬取拉勾网 很好玩的 今晚打算做成excel表格
直接贴上源代码:
# views class RegForm(forms.Form): name = forms.CharField( max_length=16, label='用户名', widgets=widgets.TextInput(attrs={"class": "form-control"}) ) pwd = forms.CharField( # 校验规则相关 label='密码', min_length=6, # widget 控制生成html代码相关的 widgets=widgets.PasswordInput(attrs={"class": "form-control"}), error_messages={ "required": "不能为空", "invalid": "格式错误", "min_length": "用户名最短6位" }) re_pwd = forms.CharField( label='密码', min_length=6, widgets=widgets.PasswordInput(attrs={"class": "form-control"}), error_messages={ "required": "不能为空", "invalid": "格式错误", "min_length": "用户名最短6位", }) email = forms.EmailField( label="邮箱", widget=widgets.EmailInput(attrs={"class": "form-control"}), error_messages={ "required": "不能为空", }) mobile = forms.CharField( label="手机", # 自己定制校验规则 validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^1[3-9][0-9]{9}$', '手机格式有误') ], widget=widgets.TextInput(attrs={"class": "form-control"}), error_messages={ "required": "不能为空", }) gender = forms.fields.ChoiceField( choices=((1, "男"), (2, "女"), (3, "保密")), label="性别", initial=3, widget=forms.widgets.RadioSelect() ) # 单选 Select hobby1 = forms.fields.ChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), label="爱好", initial=3, widget=forms.widgets.Select() ) # 多选Select hobby2 = forms.fields.MultipleChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), label="爱好", initial=[1, 3], widget=forms.widgets.SelectMultiple() ) # 单选checkbox keep = forms.fields.ChoiceField( label="是否记住密码", initial="checked", widget=forms.widgets.CheckboxInput() ) # 多选checkbox hobby3 = forms.fields.MultipleChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), label="爱好", initial=[1, 3], widget=forms.widgets.SelectMultiple(attrs={"class": "c1"}) ) # 动态从数据库区choices数据 city = forms.fields.MultipleChoiceField( choices=models.City.objects.all().values_list(), label="城市", initial=1, widget=forms.widgets.SelectMultiple() ) # 重写父类的init方法 # 实时更新数据库内容 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['city'].widget.choices = models.City.objects.all().values_list('id', 'name') def clean_name(self): value = self.cleaned_data("name") if "Alex" in value: raise ValidationError("不符合社会主义核心价值观") return value # 重写父类的clean方法 def clean(self): # 此时 通过检验的字段的数据都保存在 self.cleaned_data pwd = self.cleaned_data.get("pwd") re_pwd = self.cleaned_data.get("re_pwd") if pwd != re_pwd: self.add_error("re_pwd", ValidationError("两次密码不一致")) raise ValidationError("两次密码不一致") return self.cleaned_data def reg2(requests): form_obj = RegForm() if requests.method == 'POST': form_obj = RegForm(requests.POST) # 让form帮我们做校验 if form_obj.is_valid(): # 校验通过 # 把数据存到数据库 # 所有经过校验的数据都保存在 form_obj.cleaned_data del form_obj.cleaned_data["red_pwd"] models.UserInfo.objects.create(**form_obj.cleaned_data) return HttpResponse("注册成功") return render(requests, 'reg2.html', {'form_obj': form_obj})
models
from django.db import models # Create your models here. class UserInfo(models.Model): name = models.CharField(max_length=32, unique=True, null=False) pwd = models.CharField(max_length=32, default='doushidashuaibi') email = models.EmailField(null=True) mobile = models.CharField(max_length=11, null=True) def __str__(self): return self.name class City(models.Model): name = models.CharField(max_length=16, null=True, unique=True) def __str__(self): return self.name
reg2.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Django Form组件使用</title> <style> .c1 { list-style-type: none; } </style> </head> <body> {#<form action="/reg2/" method="post">#} {# {% csrf_token %}#} {# {{form_obj.as_p }}#} {# {{form_obj.errors.pwd }}#} {# <p><input type="submit"></p>#} {#</form>#} <!--自己逐个字段写--> <div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <form action="/reg2/" method="post" novalidate> {% csrf_token %} <div class="form-group {% if form_obj.name.errors.0 %}has-error{% endif %}"> {{ form_obj.name.label }} {{ form_obj.name }} <span class="help-block">{{ form_obj.name.errors.0 }}</span> </div> <div class="form-group {% if form_obj.pwd.errors.0 %}has-error{% endif %}"> {{ form_obj.pwd.label }} {{ form_obj.pwd }} <span class="help-block">{{ form_obj.pwd.errors.0 }}</span> </div> <div class="form-group {% if form_obj.re_pwd.errors.0 %}has-error{% endif %}"> {{ form_obj.re_pwd.label }} {{ form_obj.re_pwd }} <span class="help-block">{{ form_obj.re_pwd.errors.0 }}</span> </div> <div class="form-group {% if form_obj.email.errors.0 %}has-error{% endif %}"> {{ form_obj.email.label }} {{ form_obj.email }} <span class="help-block">{{ form_obj.email.errors.0 }}</span> </div> <div class="form-group {% if form_obj.mobile.errors.0 %}has-error{% endif %}"> {{ form_obj.mobile.label }} {{ form_obj.mobile }} <span class="help-block">{{ form_obj.mobile.errors.0 }}</span> </div> <div class="form-group {% if form_obj.city.errors.0 %}has-error{% endif %}"> {{ form_obj.city.label }} {{ form_obj.city }} <span class="help-block">{{ form_obj.city.errors.0 }}</span> </div> <div class="form-group"> <input type="submit" class="btn btn-default"> </div> </form> </div> </div> </div> </body> </html>
Django Form所有内置字段
Field required=True, 是否允许为空 widget=None, HTML插件 label=None, 用于生成Label标签或显示内容 initial=None, 初始值 help_text='', 帮助信息(在标签旁边显示) error_messages=None, 错误信息 {'required': '不能为空', 'invalid': '格式错误'} 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-01 TimeField(BaseTemporalField) 格式:11:12 DateTimeField(BaseTemporalField)格式:2015-09-01 11:12 DurationField(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.ModelMultipleChoiceField TypedChoiceField(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类型 Django Form内置字段
day73 2018-05-17 1. 内容回顾 1. 回顾了一下json数据格式 1. JS对象 和 json数据格式的互相转换 2. Python中数据 和 json数据格式的互相转换 2. AJAX 1. 我们前端往后端发请求的方式: 1. 直接在地址栏输入URL 2. a标签 3. form表单 4. AJAX HTTP请求的类型: GET POST 2. AJAX特点: 1. 异步 2. 局部刷新(偷偷发请求) 3. AJAX缺点: 请求零碎,滥用对服务端压力大 4. jQuery封装的AJAX方法: 先导入 jquery.js $.ajax({ url: "/test/", type: "post", data: {"key": "value", "key2":[[1, 2, 3], [4, 5, 6]]}, success: function(arg){ // 请求得到响应的时候,自动执行这个回调函数 console.log(arg); } }) 2. 今日内容 1. form组件的介绍 之前web开发的模式,以注册为例: 1. 要有一个注册的页面,页面里面要有form表单 --> 生成HTML代码 2. form表单要能提交数据到后端,后端要做有效性校验 --> 数据有效性校验 3. 要把校验的提示信息展示在页面上 --> 校验信息返回并展示,保存原来填写的内容 关于校验: 1. 前端通过JS代码做校验 --> 最好有 2. 后端做校验 --> 必须要有(因为前端的校验可以被跳过) 2. form组件的用法 1. from django import forms 2, 定义一个form类 class RegForm(forms.Form): user = forms.CharField() pwd = forms.CharField() email = forms.EmailField() 生成HTML: 3. 实例化一个form对象, 传递到模板语言中 4. 在目标语言中调用form对象的响应方法和属性 三种方式: 1. {{ form_obj.as_p }} 2. 单独写 {{ form_obj.pwd.label }} {{ form_obj.pwd }} 做校验: 1. form_obj = RegForm(request.POST) 2. form_obj.is_valid() 内置的正则校验器的使用 mobile = forms.CharField( label="手机", # 自己定制校验规则 validators=[ RegexValidator(r'^[0-9]+$', '手机号必须是数字'), RegexValidator(r'^1[3-9][0-9]{9}$', '手机格式有误') ], widget=widgets.TextInput(attrs={"class": "form-control"}), error_messages={ "required": "该字段不能为空", } ) 看源码: form_obj.is_valid()都干了什么? self._errors = ErrorDict() --> {} self.cleaned_data = {} self.fields.items() 字段名 字段对象 如果有错误: self._errors["name"] = "" 没有报错: self.cleaned_data["name"] = value(用户填写的值) 注意: 钩子函数(hook)的使用 def clean_xx(): """具体字段的自定义校验方法""" pass def clean(): """全局的自定义校验方法""" pass errors: <ul class="errorlist"> <li>name <ul class="errorlist"> <li>不符合社会主义核心价值观!</li> </ul> </li> <li>__all__ <ul class="errorlist nonfield"> <li>两次密码不一致</li> </ul> </li> </ul>