1.應用說明
一般在表單信息錄入中,如果存在許多重復提交的信息,我們就需要進行批量處理,比如學生信息的批量錄入。
這里一種方式就是使用xlrd模塊處理,把學生信息錄入到系統內
另外一種方式就是采用我們from組件中提供的formset來進行批量處理,實現用戶在同一頁面提交多張表單
2.相關源碼
formsets.py
def formset_factory(form, formset=BaseFormSet, extra=1, can_order=False, can_delete=False, max_num=None, validate_max=False, min_num=None, validate_min=False): """Return a FormSet for the given form class.""" if min_num is None: min_num = DEFAULT_MIN_NUM if max_num is None: max_num = DEFAULT_MAX_NUM # hard limit on forms instantiated, to prevent memory-exhaustion attacks # limit is simply max_num + DEFAULT_MAX_NUM (which is 2*DEFAULT_MAX_NUM # if max_num is None in the first place) absolute_max = max_num + DEFAULT_MAX_NUM attrs = {'form': form, 'extra': extra, 'can_order': can_order, 'can_delete': can_delete, 'min_num': min_num, 'max_num': max_num, 'absolute_max': absolute_max, 'validate_min': validate_min, 'validate_max': validate_max} return type(form.__name__ + str('FormSet'), (formset,), attrs)
該函數主要用來處理表單集
3.批量添加案例
models.py
from django.db import models class User(models.Model): user = models.CharField(max_length=32) pwd = models.CharField(max_length=32) email = models.CharField(max_length=32)
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/', views.index), ]
viewspy
from django.shortcuts import render,HttpResponse from django import forms from app01 import models """ class UserForm(forms.Form): id = forms.CharField(required=True) user = forms.CharField(required=True) pwd = forms.CharField(required=True) email = forms.CharField(required=True) """ # 簡寫版 class UserForm(forms.ModelForm): class Meta: model = models.User fields ="__all__" def index(request): # 生成一個類,它是form集合。extra設置展示的表單數量 UserFormSet = forms.formset_factory(UserForm,extra=3,) if request.method == 'GET': formset = UserFormSet() return render(request,"index.html",{'formset':formset}) formset = UserFormSet(request.POST) if formset.is_valid(): flag = False # 標志位 for row in formset.cleaned_data: if row: # **表示將字典擴展為關鍵字參數 res = models.User.objects.create(**row) if res: # 判斷返回信息 flag = True if flag: return HttpResponse('添加成功') else: return HttpResponse('添加失敗') return render(request, "index.html", {'formset': formset})
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="post"> {{ formset.management_form }} {% csrf_token %} <table border="1"> <tr> <th>用戶名</th> <th>密碼</th> <th>郵箱</th> </tr> {% for form in formset %} <tr> {% for field in form %} <td>{{ field }} {{ field.errors.0 }} </td> {% endfor %} </tr> {% endfor %} </table> <input type="submit" value="提交"> </form> </body> </html>
效果:
直接點擊提交,返回添加失敗,只添加一行數據,返回添加成功,添加部分數據:

它會返回提示信息,填寫完后查看數據庫:

4.批量修改案例
這里其實在頁面渲染出來數據,再進行修改在全部寫入即可,當中獲取它修改的表單id,以及使用initial方法
在上面的基礎上在做修改:
views.py
from django.shortcuts import render from django import forms from app01 import models class UserForm(forms.Form): id = forms.CharField(required=True) user = forms.CharField(required=True) pwd = forms.CharField(required=True) email = forms.CharField(required=True) def index(request): queryset = models.User.objects.all().values() UserFormSet = forms.formset_factory(UserForm,extra=0) if request.method == 'GET': # initial 參數用來給 ModelForm 定義初始值 formset = UserFormSet(initial=queryset) return render(request,'index.html',{'formset':formset}) formset = UserFormSet(request.POST) if formset.is_valid(): for row in formset.cleaned_data: # 刪除字典攜帶的id id = row.pop('id') models.User.objects.filter(id=id).update(**row) return render(request, 'index.html', {'formset': formset})
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .hide{ display: none; } </style> </head> <body> <form method="post"> {{ formset.management_form }} {% csrf_token %} <table border="1"> <tr> <th>用戶名</th> <th>密碼</th> <th>郵箱</th> </tr> {% for form in formset %} <tr> {% for field in form %} {% if forloop.first %} <td class="hide">{{ field }} </td> {% else %} <td>{{ field }} {{ field.errors.0 }} </td> {% endif %} {% endfor %} </tr> {% endfor %} </table> <input type="submit" value="提交"> </form> </body> </html>
效果還是和上面案例一樣,我們對於某個字段做修改:

提交至數據庫

# 這里更新的時候,需要使用到id,但是它不需要在表單中顯示出來,所以我們在html中對它做了隱藏處理
# 至於為什么這里不是用forms.ModelForm而是使用forms.Form,是因為ModelForm默認的全部字段中沒有包含id
