Django之路12——form modelform formset modelformset的各种用法
首先上结论:
form适用于对单个表单的操作,并且需要对每个字段的验证规则自定义。
modelform:适用于对用户提交的单个表单操作,字段可以用model中的表的字段来作为验证规则,适用于快速的进行增加、修改。
formset:适用于对多个表单进行操作,字段需要也可以用model中的表的字段来作为验证规则。
modelfoemset:适用于对多个表单进行操作,字段需要也可以用model中的表的字段来作为验证规则,速度可能快一些(有待考证)
form用法
后端代码

from django.forms import widgets wid_01=widgets.TextInput(attrs={"class":"form-control"})
wid_02=widgets.PasswordInput(attrs={"class":"form-control"}) class UserForm(forms.Form):
name=forms.CharField(max_length=32,
widget=wid_01
)
pwd=forms.CharField(max_length=32,widget=wid_02)
r_pwd=forms.CharField(max_length=32,widget=wid_02)
email=forms.EmailField(widget=wid_01)
tel=forms.CharField(max_length=32,widget=wid_01) def register(request): if request.method=="POST":
form=UserForm(request.POST)
if form.is_valid():
print(form.cleaned_data) # 所有干净的字段以及对应的值
else:
print(form.cleaned_data) #
print(form.errors) # ErrorDict : {"校验错误的字段":["错误信息",]}
print(form.errors.get("name")) # ErrorList ["错误信息",]
return HttpResponse("OK")
form=UserForm()
return render(request,"register.html",locals())


<form action="" method="post">
{% csrf_token %} {% for field in form %}
<div>
<label for="">{{ field.label }}</label>
{{ field }}
</div>
{% endfor %}
<input type="submit" class="btn btn-default pull-right"> </form>

modelform用法

class MenuModelForm(forms.ModelForm):
class Meta:
model = models.Menu
fields = '__all__'
widgets = {
'title': forms.TextInput(attrs={'placeholder': '请输入角色名称', 'class': 'form-control'}),
'icon': forms.RadioSelect(
choices=ICON_LIST
)
}
error_messages = {
'title': {
'required': '菜单名称不能为空',
},
'icon': {
'required': '请选择图标',
}
} def menu_add(request):
"""
添加菜单
:param request:
:return:
"""
if request.method == 'GET':
form = MenuModelForm()
else:
form = MenuModelForm(request.POST)
if form.is_valid():
print(form.data)
form.save()
return redirect(reverse('rbac:menu_list'))
return render(request, 'rbac/menu_change.html', {'form': form}) def menu_edit(request, pk):
"""
编辑菜单
:param request:
:return:
"""
obj = models.Menu.objects.filter(id=pk).first()
if not obj:
return HttpResponse('菜单不存在') if request.method == 'GET':
form = MenuModelForm(instance=obj)
return render(request, 'rbac/menu_change.html', {'form': form}) form = MenuModelForm(request.POST, instance=obj)
if form.is_valid():
form.save()
return redirect(reverse('rbac:menu_list'))


<div class="luffy-container">
<form class="form-horizontal" method="post" novalidate>
{% csrf_token %}
<div class="form-group">
<label class="col-sm-2 control-label">菜单名称:</label>
<div class="col-sm-6">
{{ form.title }} </div>
<div class="col-sm-offset-1 col-sm-2">
<input type="submit" value="保 存" class="btn btn-primary">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">图标:</label>
<div class="col-sm-7 icon-area">
{{ form.icon }}
</div>
<div class="col-sm-3">
<div>{{ form.title.errors.0 }}</div>
<div>{{ form.icon.errors.0 }}</div>
</div>
</div> </form>
</div>

formset用法

class MultiPermissionForm(forms.Form):
id = forms.IntegerField(
widget=forms.HiddenInput(),
required=False
)
title = forms.CharField(
widget=forms.TextInput(attrs={'class': "form-control"})
)
url = forms.CharField(
widget=forms.TextInput(attrs={'class': "form-control"})
)
name = forms.CharField(
widget=forms.TextInput(attrs={'class': "form-control"})
)
menu_id = forms.ChoiceField(
choices=[(None, '-----')],
widget=forms.Select(attrs={'class': "form-control"}),
required=False, ) pid_id = forms.ChoiceField(
choices=[(None, '-----')],
widget=forms.Select(attrs={'class': "form-control"}),
required=False,
) def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['menu_id'].choices += models.Menu.objects.values_list('id', 'title')
self.fields['pid_id'].choices += models.Permission.objects.filter(pid__isnull=True).exclude(
menu__isnull=True).values_list('id', 'title') def clean_pid_id(self):
menu = self.cleaned_data.get('menu_id')
pid = self.cleaned_data.get('pid_id')
if menu and pid:
raise forms.ValidationError('菜单和根权限同时只能选择一个')
return pid def add(request):
"""
增加
:param request:
:return:
"""
MultiPermissionFormSet = formset_factory(MultiPermissionForm, extra=0)
if request.method == 'GET':
form = MultiPermissionFormSet()
return render(request,'list.html',{'form':form}
form = MultiPermissionFormSet(request.post)
if form.is_valid():
return redict('url')
else:
......... def edit(request):
"""
修改
:param request:
:return:
"""
MultiPermissionFormSet = formset_factory(MultiPermissionForm, extra=0)
if request.method == 'GET':
form = MultiPermissionFormSet('数据')
# formset是支持批量修改的所以 这里传入的数据一定要是可迭代对象,并且里面的
数据类型是字典或者对象
return render(request,'list.html',{'form':form}
form = MultiPermissionFormSet(request.post)
if form.is_valid():
return redict('url')
else:
.........


<div class="luffy-container">
<form method="post" action="?type=generate">
{% csrf_token %}
{{ form.management_form }}
# 这里一定要记得写这一步
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">
<i class="fa fa-binoculars" aria-hidden="true"></i> 待新建权限列表
<button class="right btn btn-primary btn-xs" style="padding: 2px 8px;margin: -3px;">
<i class="fa fa-save" aria-hidden="true"></i>
新建
</button>
</div>
<div class="panel-body" style="color: #9d9d9d;">
注意:路由系统中自动发现且数据库中不存在的路由。
</div> <table class="table table-bordered">
<thead>
<tr>
<th>序号</th>
<th>名称</th>
<th>URL</th>
<th>别名</th>
<th>所属菜单</th>
<th>根权限</th>
</tr>
</thead>
<tbody>
{% for form in generate_formset %} <tr>
<td style="vertical-align: middle;">{{ forloop.counter }}</td>
{% for field in form %} # 这里在渲染标签的时候一定要渲染 id这个标签 这个很重要不然会报错 这里是写了两个fou循环 所以自动渲染了id标签
{% if forloop.first %}
<td class="hide">
{% else %}
<td>
{% endif %}
{{ field }}<span style="color: firebrick;">{{ field.errors.0 }}</span>
</td>
{% endfor %}
{% endfor %}
</tbody>
</table>
</div>
</form>

modelformset用法

class StudyRecordModelForm(forms.ModelForm):
class Meta:
model = models.StudyRecord
fields = ['student','record','score','homework_note'] def changelist_view(self,request):
ccid = request.GET.get('ccid')
model_formset_cls = modelformset_factory(models.StudyRecord,StudyRecordModelForm,extra=0)
queryset = models.StudyRecord.objects.filter(course_record_id=ccid)
if request.method == "GET":
formset = model_formset_cls(queryset=queryset)
# 这里UI定是个可迭代对象,因为modelformset是操作多表的,里面的数据类型可以为字典或者对象
return render(request,'study_record.html',{'formset':formset}) formset = model_formset_cls(data=request.POST)
print(request.POST)
if formset.is_valid():
formset.save()
return redirect('/stark/crm/studyrecord/list/?ccid=%s' %ccid )
return render(request, 'study_record.html', {'formset': formset})


<div class="panel panel-default">
<div class="panel-heading">学习记录</div>
<div class="panel-body">
<div style="width: 680px;margin: 0 auto;">
<form method="post">
{% csrf_token %}
{{ formset.management_form }}
# 这里一定要加这句代码 <table class="table table-bordered">
<thead>
<tr>
<th>姓名</th>
<th>考勤</th>
<th>作业成绩</th>
<th>作业评语</th>
</tr>
</thead>
<tbody>
{% for form in formset %}
<tr>
{{ form.id }}
# 这里只写了一层for循环,所以手动写字段,必须把id字段写上
<td>{{ form.instance.student }}</td>
<td>{{ form.record }} {{ form.record.errors.0 }}</td>
<td>{{ form.score }} {{ form.score.errors.0 }}</td>
<td>{{ form.homework_note }} {{ form.homework_note.errors.0 }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<input type="submit" value="保存">
</form>
</div>
</div>
</div>

以上为这四种的区别和用法。
Django之路12——form modelform formset modelformset的各种用法的更多相关文章
- form modelform formset modelformset的各种用法
form modelform formset modelformset的各种用法 首先上结论: form适用于对单个表单的操作,并且需要对每个字段的验证规则自定义. modelform:适用于对用 ...
- django基础 -- 10.form , ModelForm ,modelformset
一.生成页面可用的 HTML标签 1.form 所有内置字段 Field required=True, 是否允许为空 widget=None, HTML插件 label=None, 用于生成Label ...
- 12.Django基础十之Form和ModelForm组件
一 Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户 ...
- Django基础十之Form和ModelForm组件
一 Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户 ...
- {Django基础十之Form和ModelForm组件}一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 ModelForm
Django基础十之Form和ModelForm组件 本节目录 一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 Model ...
- day 64 Django基础十之Form和ModelForm组件
Django基础十之Form和ModelForm组件 本节目录 一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 Mod ...
- Django之Model、Form、ModelForm区别
本节内容: 1:Model https://www.cnblogs.com/shuai1991/p/10844662.html 2:Form ...
- python 学习笔记十七 django深入学习二 form,models
表单 GET 和 POST 处理表单时候只会用到GET 和 POST 方法. Django 的登录表单使用POST 方法,在这个方法中浏览器组合表单数据.对它们进行编码以用于传输.将它们发送到服务器然 ...
- Django之路: 基本命令与网址进阶
一.Django 基本命令 温馨提示:如果你想学习Django,那么就请您从现在开始按照笔记记录一步一步的用手把代码敲出来,千万不要偷懒哦..... 1.创建一个Django project djan ...
随机推荐
- ubuntu “下列的软件包有不能满足的依赖关系” 问题
前阵子,刚安装Ubuntu时,安装vim的问题,现在些出来分享一下. apt-get install vim 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... 完成 ...
- ICPC World Finals 2019 题解
[A]Azulejos 题意简述: 有两排瓷砖,每排都有 \(n\) 个,每个瓷砖有高度 \(h_i\) 和价格 \(p_i\) 两种属性. 你需要分别重新排列这两排瓷砖,使得同一排的瓷砖满足价格不降 ...
- 深入分析Linux自旋锁【转】
转自:http://blog.chinaunix.net/uid-20543672-id-3252604.html 前言: 在复习休眠的过程中,我想验证自旋锁中不可休眠,所以编写了一个在自旋锁中休眠的 ...
- TYpeScript接口的使用
1.接口中的属性值的使用: // 作用是强制类型检查 interface Iperson { name: string; age: string; } class Person { construct ...
- 001_vagrant利器
一. 这是一个关于Vagrant的学习系列,包含如下文章: Vagrant入门 http://www.cnblogs.com/davenkin/p/vagrant-virtualbox.html 创建 ...
- 转:MySQL如何修改密码
转:https://www.cnblogs.com/yang82/p/7794712.html. 第一种方式: 最简单的方法就是借助第三方工具Navicat for MySQL来修改,方法如下: 1. ...
- JNI和NDK
作者:十岁的小男孩 QQ:929994365 心之安处即是吾乡 前言 本文试图通过解答以下三个问题来达到学习JNI和NDK的目的.是什么?有什么用?怎么用?文章内容前三节来自下面第一个链接的博主共享, ...
- pytest十一:函数传参和 firture 传参数 request
为了提高代码的复用性,我们在写用例的时候,会用到函数,然后不同的用例去调用这个函数.比如登录操作,大部分的用例都会先登录,那就需要把登录单独抽出来写个函数,其它用例全部的调用这个登录函数就行.但是登录 ...
- OGNL(对象图导航语言)学习
一.关于OGNL(Object-Graph Navigation Language),一种可以方便地操作对象属性的开源表达式语言. 特点: 1)支持对象方法调用,形式如:objName.method ...
- 基于TCPCopy的仿真压测方案
一.tcpcopy工具介绍 tcpcopy 是一个分布式在线压力测试工具,可以将线上流量拷贝到测试机器,实时的模拟线上环境,达到在程序不上线的情况下实时承担线上流量的效果,尽早发现 bug,增加上线信 ...