Formset的用途
一般批量处理Form表单时使用
Formset的简单例子
数据库表结构
# models.py
from django.db import models
# Create your models here.
class Permission(models.Model):
"""
权限表
"""
title = models.CharField(verbose_name='标题', max_length=32)
alias = models.CharField(verbose_name='url别名', max_length=32, unique=True)
url = models.CharField(verbose_name='含正则的URL', max_length=128, null=True, blank=True)
is_menu = models.BooleanField(verbose_name='是否可以做菜单', default=False)
icon = models.CharField(verbose_name='图标', max_length=32, null=True, blank=True)
parent_menu = models.ForeignKey(verbose_name='父菜单标志', to='self', null=True, on_delete=models.CASCADE, blank=True)
def __str__(self):
return self.title
前端实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>表单</h1>
<form method="post">
{% csrf_token %}
{{ formset.management_form }}
<table border="1">
<thead>
<tr>
<th>标题</th>
<th>别名</th>
<th>URL</th>
<th>是否作为菜单</th>
<th>父菜单</th>
</tr>
</thead>
<tbody>
{% for form in formset %}
<tr>
{% for field in form %}
<td>{{ field }} <span style="color: red;">{{ field.errors.0 }}</span></td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
<input type="submit" value="提交">
</form>
</body>
</html>
控制层
from django.shortcuts import render, HttpResponse
from django.forms import formset_factory
# Create your views here.
from app01.forms import MultiForm
from app01 import models
def formset(request):
# 创建formset对象
formset_class = formset_factory(MultiForm, extra=2)
if request.method == 'GET':
formset = formset_class()
return render(request, 'app01/formset.html', {'formset': formset})
formset = formset_class(data=request.POST)
if formset.is_valid():
flag = True
post_row_list = formset.cleaned_data
# 校验对象是否在数据库中唯一,不唯一则添加报错Formset对象并显示在前端页面
for i in range(0, formset.total_form_count()):
row = post_row_list[i]
try:
obj = models.Permission(**row)
obj.validate_unique()
obj.save()
except Exception as e:
formset.errors[i].update(e)
flag = False
else:
return HttpResponse('提交成功') if flag else render(request, 'app01/formset.html', {'formset': formset})
else:
return render(request, 'app01/formset.html', {'formset': formset})