二十三. Django Form组件局部钩子与全局钩子 和注册页面使用
一. Form组件 注册页面使用
https://www.jianshu.com/p/7e61160dc689
https://download.csdn.net/download/baobao267/10722491 Django之Form表单验证及Ajax验证方式汇总
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内置字段
我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来。
与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确。如果用户输入的内容有错误就需要在页面
上相应的位置显示对应的错误信息.。
Django form组件就实现了上面所述的功能。
总结一下,其实form组件的主要功能如下:
生成页面可用的HTML标签
对用户提交的数据进行校验
保留上次输入内容
1. FORM组件渲染方式一(可以使用但是不会保留上次输入正确的值会清空)
models from django.db import models # Create your models here. class UserInfo(models.Model): name=models.CharField(max_length=32) pwd=models.CharField(max_length=32) email=models.EmailField() tel=models.CharField(max_length=32)
views
from django.forms import widgets
from myapp import models
from django.forms import fields
from django import forms
注意 : form组件字段名必须和模板中input的name="" 属性名一样 还要和model字段名一样 例如标记的 name
class Forms(forms.Form): name=forms.CharField(min_length=2,required=True,error_messages={ "required":"不能为空!!!", "min_length":"用户不得低于2位!!" }) pwd=forms.CharField(min_length=3,required=True,error_messages={ "min_length":"密码不得低于3位!!", 'required':'密码不能为空', }) email=forms.EmailField(min_length=2,required=True,error_messages={ "invalid":"格式错误", "min_length":"密码不得低于两位!!", 'required': '邮件不能为空', }) tel=forms.IntegerField(required=True,error_messages={ "invalid":"格式错误", 'required': '电话不能为空' }) def reg(request): if request.method=="POST": form_li = Forms(request.POST) # 绑定上面类定义中的验证信息 if form_li.is_valid(): # 是否验证 is_valid() print (form_li.cleaned_data,"11111111111111") models.UserInfo.objects.create(**form_li.cleaned_data) 所有验证正确写入数据库 return HttpResponse("ok") else: print (form_li.errors) print (form_li.errors.get("name")) err=form_li.errors return render(request,"login.html",{"err":err}) else: form=Forms() return render(request, "login.html",{"form":form})
templates <!DOCTYPE html> <html lang="en"> <head> {% load staticfiles %} <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1">、 <title>注册页面</title> <link rel="stylesheet" type="text/css" href="{%static 'css/bootstrap.min.css'%}"> </head> <body> <h1 style="text-align: center">FORM组件注册</h1> <div class="container"> <div class="row"> <form method="post" action="/reg/" novalidate class="form-horizontal"> {%csrf_token %} <div class="form-group"> <label for="user"> 用户:</label> <input type="text" name="name" placeholder="请输入用户名!!" class="form-control"> <span class="error" style="color: red">{{ err.name.0 }}</span> </div> <div class="form-group"> <label for="pwd"> 密码:</label> <input type="text" name="pwd" class="form-control" placeholder="请输入用密码!!"> <span class="error" style="color: red">{{ err.pwd.0 }}</span> </div> <div class="form-group"> <label for="em">邮箱:</label> <input type="email" name="email" class="form-control" placeholder="请输入邮箱!!"> <span class="error" style="color: red">{{ err.email.0 }}</span> </div> <div class="form-group"> <label for="tel">电话:</label> <input type="text" name="tel" class="form-control" placeholder="请输入电话!!"> <span class="error" style="color: red">{{ err.tel.0 }}</span> </div> <button type="reset" class="btn btn-warning pull-left">重置</button> <button type="submit" class="btn btn-success pull-right">提交</button> </form> </div> </div> </body> </html>
注意: 当用户输错之后 再次输入 上次的内容不会保留在input框 -->不会保留上次输入内容
2.FORM组件渲染方式二(不推荐)
templates
<!DOCTYPE html> <html lang="en"> <head> {% load staticfiles %} <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1">、 <title>注册页面</title> <link rel="stylesheet" type="text/css" href="{%static 'css/bootstrap.min.css'%}"> </head> <body> <h1 style="text-align: center">FORM组件注册</h1> <div class="container"> <div class="row"> <form method="post" action="/reg/" novalidate class="form-horizontal"> {%csrf_token %} {{ form.as_p }} <button type="reset" class="btn btn-warning pull-left">重置</button> <button type="submit" class="btn btn-success pull-right">提交</button> </form> </div> </div> </body> </html>
3.FORM组件渲染 方式三(推荐 Form渲染出来的input标签 会保留上次输入正确的值 不会清空)
views from django.shortcuts import render, HttpResponse, redirect from django.forms import widgets from myapp import models from django.forms import fields from django import forms
class Forms(forms.Form): name=forms.CharField(label="用户",min_length=2,initial="请输入用户名!!",required=True,error_messages={ "required":"不能为空!!!", "min_length":"用户不得低于2位!!" }, widget=widgets.TextInput(attrs={"class":"form-control"})) pwd=forms.CharField(label="密码",min_length=3,required=True,error_messages={ "min_length":"密码不得低于3位!!", 'required':'密码不能为空', },widget=widgets.TextInput(attrs={"class":"form-control"})) email=forms.EmailField(label="邮件",min_length=2,required=True,error_messages={ "invalid":"格式错误", "min_length":"密码不得低于两位!!", 'required': '邮件不能为空', },widget=widgets.EmailInput(attrs={"class":"form-control"})) tel=forms.CharField(min_length=6,label="电话",required=True,error_messages={ "invalid":"格式错误", 'required': '电话不能为空', 'min_length':'不能小于6位数' },widget=widgets.TextInput(attrs={"class":"form-control"})) def reg(request): if request.method=="POST": form= Forms(request.POST) # 绑定上面类定义中的验证信息 if form.is_valid(): # 是否验证 is_valid() print (form.cleaned_data,"11111111111111") models.UserInfo.objects.create(**form_li.cleaned_data) print (form.cleaned_data["name"], "***********") return HttpResponse("ok") else: err=form.errors print (err) # return render(request,"login.html",locals()) return render(request, "login.html",{"err":err,"form":form}) # 注意这个form是有值的 格式输入正确了就保留input里面的值 else: form=Forms() # return render(request, "login.html",locals()) return render(request, "login.html",{"form":form}) # 这和form没有值只是负责渲染页面
from django.shortcuts import render, HttpResponse, redirect from django.forms import widgets from myapp import models from django.forms import fields from django import forms def index(request): return HttpResponse('哈哈哈哈哈哈哈哈哈哈') class Forms(forms.Form): name=forms.CharField(label="用户",min_length=2,initial="请输入用户名!!",required=True,error_messages={ "required":"不能为空!!!", "min_length":"用户不得低于2位!!" }, widget=widgets.TextInput(attrs={"class":"form-control"})) pwd=forms.IntegerField(label="密码",required=True,error_messages={ 'required':'密码不能为空' },widget=widgets.PasswordInput(attrs={"class":"form-control"})) email=forms.EmailField(label="邮件",min_length=2,required=True,error_messages={ "invalid":"格式错误", "min_length":"密码不得低于两位!!", 'required': '邮件不能为空', },widget=widgets.EmailInput(attrs={"class":"form-control"})) tel=forms.CharField(min_length=6,label="电话",required=True,error_messages={ "invalid":"格式错误", 'required': '电话不能为空', 'min_length':'不能小于6位数' },widget=widgets.TextInput(attrs={"class":"form-control"})) def reg(request): if request.method=="POST": form= Forms(request.POST) # 绑定上面类定义中的验证信息 if form.is_valid(): # 是否验证 is_valid() print (form.cleaned_data,"11111111111111") models.UserInfo.objects.create(**form.cleaned_data) print (form.cleaned_data["name"], "***********") return HttpResponse("ok") else: err=form.errors print (err) # return render(request,"login.html",locals()) return render(request, "login.html",{"err":err,"form":form}) # 注意这个form是有值的 格式输入正确了就保留input里面的值 else: form=Forms() # return render(request, "login.html",locals()) return render(request, "login.html",{"form":form}) # 这和form没有值只是负责渲染除页面
templates
<!DOCTYPE html> <html lang="en"> <head> {% load staticfiles %} <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1">、 <title>注册页面</title> <link rel="stylesheet" type="text/css" href="{%static 'css/bootstrap.min.css'%}"> </head> <body> <h1 style="text-align: center">FORM组件注册</h1> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-3"> <form method="post" action="/reg/" novalidate > {%csrf_token %} 用户: <p>{{ form.name }}<span class="error" style="color: red">{{ err.name.0 }}</span></p> 密码: <p>{{ form.pwd }}<span class="error" style="color: red">{{ err.pwd.0 }}</span> </p> 邮箱: <p>{{ form.email}}<span class="error" style="color: red">{{ err.email.0 }}</span> </p> 电话: <p>{{ form.tel}}<span class="error" style="color: red">{{ err.tel.0 }}</span> </p> <input type="submit" value="提交" > </form> </div> </div> </div> </body> </html>
urls
path(r'reg/', views.reg, name='regs'),
4 .FORM组件渲染 方式三(推荐 Form渲染完全出页面 会保留上次输入正确的值 不会清空)
views from django.shortcuts import render, HttpResponse, redirect from django.forms import widgets from myapp import models from django.forms import fields from django import forms def index(request): return HttpResponse('哈哈哈哈哈哈哈哈哈哈') class Forms(forms.Form): name=forms.CharField(label="用户",min_length=2,initial="请输入用户名!!",required=True,error_messages={ "required":"不能为空!!!", "min_length":"用户不得低于2位!!" }, widget=widgets.TextInput(attrs={"class":"form-control"})) pwd=forms.IntegerField(label="密码",required=True,error_messages={ 'required':'密码不能为空' },widget=widgets.PasswordInput(attrs={"class":"form-control"})) email=forms.EmailField(label="邮件",min_length=2,required=True,error_messages={ "invalid":"格式错误", "min_length":"密码不得低于两位!!", 'required': '邮件不能为空', },widget=widgets.EmailInput(attrs={"class":"form-control"})) tel=forms.CharField(min_length=6,label="电话",required=True,error_messages={ "invalid":"格式错误", 'required': '电话不能为空', 'min_length':'不能小于6位数' },widget=widgets.TextInput(attrs={"class":"form-control"})) def reg(request): if request.method=="POST": form= Forms(request.POST) # 绑定上面类定义中的验证信息 if form.is_valid(): # 是否验证 is_valid() print (form.cleaned_data,"11111111111111") models.UserInfo.objects.create(**form.cleaned_data) print (form.cleaned_data["name"], "***********") return HttpResponse("ok") else: err=form.errors print (err) # return render(request,"login.html",locals()) return render(request, "login.html",{"err":err,"form":form}) # 注意这个form是有值的 格式输入正确了就保留input里面的值 else: form=Forms() # return render(request, "login.html",locals()) return render(request, "login.html",{"form":form}) # 这和form没有值只是负责渲染除页面 #
<!DOCTYPE html> <html lang="en"> <head> {% load staticfiles %} <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1">、 <title>注册页面</title> <link rel="stylesheet" type="text/css" href="{%static 'css/bootstrap.min.css'%}"> </head> <body> <h1 style="text-align: center">FORM组件注册</h1> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-3"> <form method="post" action="/reg/" novalidate > {%csrf_token %} {%for filed in form %} <div class="form-group"> <label>{{ filed.label }}:</label> {{ filed }} <span class="errors">{{ filed.errors.0 }}</span> </div> {% endfor %} <input type="submit" value="提交" class="btn btn-success pull-right"> </form> </div> </div> </div> </body> </html>
二.方式四 局部钩子与全局钩子(推荐 Form渲染完全出页面 会保留上次输入正确的值 不会清空) 完美
我们在Fom类中定义 clean_字段名() 方法,就能够实现对特定字段进行校验。
我们在Fom类中定义 clean() 方法,就能够实现对字段进行全局校验。
from django.db import models # Create your models here. class UserInfo(models.Model): name=models.CharField(max_length=32) pwd=models.CharField(max_length=32) email=models.EmailField() tel=models.CharField(max_length=32)
path(r'reg/', views.reg, name='regs'),
from django.shortcuts import render, HttpResponse, redirect from django.forms import widgets from myapp import models from django.forms import fields from django import forms from django.core.exceptions import ValidationError def index(request): return HttpResponse('哈哈哈哈哈哈哈哈哈哈')
class Forms(forms.Form): name=forms.CharField(label="用户",min_length=2,initial="请输入用户名!!",required=True,error_messages={ "required":"不能为空!!!", "min_length":"用户不得低于2位!!" }, widget=widgets.TextInput(attrs={"class":"form-control"})) pwd=forms.CharField( label="密码", required=True, min_length = 2, error_messages={ 'required':'密码不能为空', 'min_length': '标题最少为5个字符' },widget=widgets.PasswordInput(attrs={"class":"form-control"})) r_pwd = forms.CharField( required=True, label="确认密码", min_length=2, error_messages={ "required":"不能为空!!", 'min_length': '标题最少为5个字符' }, widget=widgets.PasswordInput(attrs={"class":"form-control"}) ) email=forms.EmailField(label="邮件",min_length=2,required=True,error_messages={ "invalid":"格式错误", "min_length":"密码不得低于两位!!", 'required': '邮件不能为空', },widget=widgets.EmailInput(attrs={"class":"form-control"})) tel=forms.CharField(min_length=6,label="电话",required=True,error_messages={ "invalid":"格式错误", 'required': '电话不能为空', 'min_length':'不能小于6位数' },widget=widgets.TextInput(attrs={"class":"form-control"})) # 局部钩子 clean_name def clean_name(self): val = self.cleaned_data.get("name") if not val.isdigit(): return val else: raise ValidationError("用户名不能是纯数字!") # 定义全局的钩子, clean def clean(self): # 定义全局的钩子,用来校验密码和确认密码字段是否相同 pwd = self.cleaned_data.get("pwd") r_pwd = self.cleaned_data.get("r_pwd") if pwd == r_pwd: return self.cleaned_data else: raise ValidationError('两次密码不一致!') def reg(request): if request.method=="POST": form= Forms(request.POST) # 绑定上面类定义中的验证信息 if form.is_valid(): # 是否验证 is_valid() # models.UserInfo.objects.create(**form.cleaned_data) name=form.cleaned_data["name"] pwd = form.cleaned_data["pwd"] emails= form.cleaned_data["email"] tel = form.cleaned_data["tel"] print (name,pwd,emails,tel) models.UserInfo.objects.create(name=name,pwd=pwd,email=emails,tel =tel ) print (form.cleaned_data, "11111111111111") return HttpResponse("ok") else: err=form.errors get_err= form.errors.get("__all__") print(get_err,"9999999999") # 两次密码不一致! 9999999999 # return render(request,"login.html",locals()) return render(request, "login.html",{"err":err,"form":form,"get_err":get_err}) # 注意这个form是有值的 格式输入正确了就保留input里面的值 else: form=Forms() # return render(request, "login.html",locals()) return render(request, "login.html",{"form":form}) # 这和form没有值只是负责渲染除页面
<!DOCTYPE html> <html lang="en"> <head> {% load staticfiles %} <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1">、 <title>注册页面</title> <link rel="stylesheet" type="text/css" href="{%static 'css/bootstrap.min.css'%}"> </head> <body> <h1 style="text-align: center">FORM组件注册</h1> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-3"> <form method="post" action="/reg/" novalidate > {%csrf_token %} {%for filed in form %} <div class="form-group"> <label>{{ filed.label }}:</label> {{ filed }}<span style="color: red" class="errors">{{ filed.errors.0 }}</span> {% if filed.label == "确认密码"%} <span style="color: red" class="errors">{{ get_err.0 | default:"" }}</span> {% endif %} </div> {% endfor %} <input type="submit" value="提交" class="btn btn-success pull-right"> </form> </div> </div> </div> </body> </html>
五. 其他 下拉框 单选框等
https://www.cnblogs.com/liwenzhou/p/8747872.html
from django.shortcuts import render, HttpResponse, redirect from django.forms import widgets from myapp import models from django.forms import fields from django import forms from django.core.exceptions import ValidationError def index(request): return HttpResponse("1111") class TestForm(forms.Form): user=fields.CharField( required=True, # 不能为空 max_length=12, # 最大长度 min_length=3, # 最小长度 error_messages={}, # 错误提示 label="用户 ", initial="请输入用户名!!!!" , widget=widgets.TextInput(attrs={"class":"form-control"}), ) age=fields.IntegerField( label="年龄 ", # 最小值 error_messages={" max_value":"给定的参数太大了!!!!!"}, widget=widgets.TextInput(attrs={"class": "form-control"}), ) email=fields.EmailField( label="邮件 ", widget=widgets.EmailInput(attrs={"class": "form-control"}), ) img=fields.FileField( label="上传图片 ", widget=widgets.ClearableFileInput(), ) # ChoiceField 选择 city=fields.ChoiceField( label="城市 ", choices=[(1,"村长",),(2,"上海",),(3,"深圳",),(4,"广州",)], initial=3, widget=forms.widgets.Select() ) bobby=fields.MultipleChoiceField( label="爱好 ", choices=[(1,"打篮球",),(2,"跑步",),(3,"健身",),(4,"打羽毛球",)], initial=[1], widget=forms.widgets.CheckboxSelectMultiple() ) r = fields.CharField( label="单选", initial=2, widget=widgets.RadioSelect(choices=((1,'上海1'),(2,'北京2'),)) ) s = fields.ChoiceField( label="单选2", choices=((1, '上111海'), (2, '北222京'), (3, '北333京')), initial=2, widget=widgets.RadioSelect ) xoo=fields.FilePathField( label="路径 ", path="myapp" ) # 单选下拉框 xdb = fields.CharField( label="单选下啦写法1 ", widget=widgets.Select(choices=[(1, "打篮球1",), (2, "跑步2",), (3, "健身3",), (4, "打羽毛球4",)]) ) # 单选下拉框 db = fields.IntegerField( label="单选下啦写法2 ", widget=widgets.Select(choices=[(1, "打篮球1",), (2, "跑步2",), (3, "健身3",), (4, "打羽毛球4",)]) ) # 单选下拉框 b = fields.ChoiceField( label="单选下啦写法3 ", choices=[(1, "打篮球5",), (2, "跑步6",), (3, "健身7",), (4, "打羽毛球8",)], ) # 单checkbox u = fields.CharField( label="单checkbox", widget=widgets.CheckboxInput() ) # 多选checkbox,值为列表 e = fields.MultipleChoiceField( label=" 多选checkbox,值为列表", initial=[2, ], choices=((1, '上海'), (2, '北京'),), widget=widgets.CheckboxSelectMultiple ) # 单radio,值为字符串 aaa= fields.CharField( label="单radio,值为字符串", initial=2, widget=widgets.RadioSelect(choices=((1, '上海1'), (2, '北京2'),)) ) # 单radio,值为字符串 saa = fields.ChoiceField( label="单radio,值为字符串", choices=((1, '上111海'), (2, '北222京'), (3, '北333京')), initial=2, widget=widgets.RadioSelect ) """ class LoverForms(forms.Form): price=fields.IntegerField() user_id=fields.IntegerField( # widget=widgets.Select(choices=[(0,"张杰"),(1,"杨过"),(2,"古龙"),]), widget=widgets.Select(choices=models.UserInfo.objects.values_list("id","username")) ) # 特殊 的单选或多选时 数据源是否能事实更新 # __init__ 是初始化数据 就是程序只启动一次 在页面刷新 就可以加载数据库的数据 这样就不用每次去启动程序加载数据库里面的数据 def __init__(self,*args,**kwargs): super(LoverForms,self).__init__(*args,**kwargs) # 这里会拷贝self 字段 self.fields["user_id"].widget.choices=choices=models.UserInfo.objects.values_list("id","username") """ def reg(request): if request.method=="POST": form=TestForm(request.POST,request.FILES) if form.is_valid(): return HttpResponse("1111") else: form=TestForm() return render(request,"login.html",{"form":form})
<!DOCTYPE html> <html lang="en"> <head> {% load staticfiles %} <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1">、 <title>注册页面</title> <link rel="stylesheet" type="text/css" href="{%static 'css/bootstrap.min.css'%}"> </head> <body> <h1 style="text-align: center">FORM组件注册</h1> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-3"> <form method="post" action="/reg/" novalidate > {%csrf_token %} {%for filed in form %} <div class="form-group"> <label>{{ filed.label }}:</label> {{ filed }} </div> {% endfor %} <input type="submit" value="提交" class="btn btn-success pull-right"> </form> </div> </div> </div> </body> </html>
choice字段注意事项 和数据库实时更新
from django.shortcuts import render, HttpResponse, redirect from django.forms import widgets from myapp import models from django.forms import fields from django import forms from django.core.exceptions import ValidationError def index(request): return HttpResponse("1111") class TestForm(forms.Form): name=forms.CharField(label="用户:",min_length=2) city = fields.ChoiceField( label="城市:", choices=models.Ctiy.objects.all().values_list("id","name"), initial=1, widget=forms.widgets.Select() ) # 重写父类方法 和数据库中数据实时更新 def __init__(self, *args, **kwargs): super(TestForm,self).__init__(*args, **kwargs) self.fields['city'].choices = models.Ctiy.objects.all().values_list('id', 'name') def reg(request): if request.method=="POST": form=TestForm(request.POST,request.FILES) if form.is_valid(): return HttpResponse("1111") else: form=TestForm() aa=models.Ctiy.objects.all().values_list("id","name") print(aa) return render(request,"login.html",{"form":form})
from django.db import models # Create your models here. class UserInfo(models.Model): name=models.CharField(max_length=32) pwd=models.CharField(max_length=32) email=models.EmailField() tel=models.CharField(max_length=32) class Ctiy(models.Model): name=models.CharField(max_length=20,null=True,unique=True) def __str__(self): return self.name
<!DOCTYPE html> <html lang="en"> <head> {% load staticfiles %} <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1">、 <title>注册页面</title> <link rel="stylesheet" type="text/css" href="{%static 'css/bootstrap.min.css'%}"> </head> <body> <form method="POST" action="/reg/" id="fm"> {% for field in form %} {{ field.label }} {{ field }} {% endfor %} <form> </body> </html>
其他
from django.shortcuts import render,HttpResponse,redirect # from .models import UserInfo from myapp import models # 启动服务器 # D:\04learnpython\01Web_Djang\webpython>python manage.py runserver # form组件 来争对用户验证 from myapp.Forms import UserForm """from django import forms from django.forms import fields # 创建验证表单信息 生成input class UserForm(forms.Form): username=fields.CharField() email=fields.EmailField()""" # 显示 def user(request): user_list=models.UserInfo.objects.all() return render(request,"html_app/01user.html",{"aa":user_list}) # 添加 def add_user(request): if request.method=="GET": obj=UserForm() # 创建的类 return render(request,"html_app/02add_user.html",{"bb":obj}) else: obc=UserForm(request.POST) if obc.is_valid(): # 去判断form的验证 # print(obc.cleaned_data) models.UserInfo.objects.create(**obc.cleaned_data) return redirect("/myapp/user/") # 重定向 else: return render(request,"html_app/02add_user.html",{"cc":obc}) # 编辑 def edit_user(request,nid): if request.method=="GET": data=models.UserInfo.objects.filter(id=nid).first() aa=UserForm({"username":data.username,"email":data.email}) return render(request,"html_app/03edit_user.html",{"bb":aa,"nid":nid}) else : cc=UserForm(request.POST) if cc.is_valid(): models.UserInfo.objects.filter(id=nid).update(**cc.cleaned_data) return redirect("/myapp/user/") else: return render(request,"html_app/03edit_user.html",{"bb":aa})